| | 1 | {{{TranslatedPages(revision=10)}}} |
| | 2 | Nog enkele voorbeelden in Python: |
| | 3 | |
| | 4 | Exporteer een verzameling routes naar een Garmin GPX-bestand: |
| | 5 | |
| | 6 | |
| | 7 | {{{#!python |
| | 8 | #!/bin/jython |
| | 9 | ''' |
| | 10 | RWN2Garmin.py - Numbered networks to Garmin GPX file converter |
| | 11 | This code is released under the GNU General |
| | 12 | Public License v2 or later. |
| | 13 | |
| | 14 | The GPL v3 is accessible here: |
| | 15 | http://www.gnu.org/licenses/gpl.html |
| | 16 | |
| | 17 | The GPL v2 is accessible here: |
| | 18 | http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
| | 19 | |
| | 20 | It comes with no warranty whatsoever. |
| | 21 | |
| | 22 | This code illustrates how to use Jython to: |
| | 23 | * work with selected items or how to process all the primitives of a certain kind (node, way, relation) |
| | 24 | |
| | 25 | ''' |
| | 26 | from javax.swing import JOptionPane, JDialog |
| | 27 | from java.awt.event import ActionListener, ActionEvent |
| | 28 | from org.openstreetmap.josm import Main |
| | 29 | import org.openstreetmap.josm.command as Command |
| | 30 | import org.openstreetmap.josm.data.osm.Node as Node |
| | 31 | import org.openstreetmap.josm.data.osm.Way as Way |
| | 32 | import org.openstreetmap.josm.data.osm.TagCollection as TagCollection |
| | 33 | import org.openstreetmap.josm.data.osm.DataSet as DataSet |
| | 34 | import time |
| | 35 | |
| | 36 | def getMapView(): |
| | 37 | if Main.main and Main.main.map: |
| | 38 | return Main.main.map.mapView |
| | 39 | else: |
| | 40 | return None |
| | 41 | |
| | 42 | mv = getMapView() |
| | 43 | f = open('C:/export.gpx', 'w') |
| | 44 | f.write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n') |
| | 45 | 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') |
| | 46 | f.write('<!-- All data by OpenStreetMap, licensed under cc-by-sa-2.0 (http://creativecommons.org/licenses/by-sa/2.0/). -->\n') |
| | 47 | if mv and mv.editLayer and mv.editLayer.data: |
| | 48 | #selectedNodes = mv.editLayer.data.getSelectedNodes() |
| | 49 | #selectedWays = mv.editLayer.data.getSelectedWays() |
| | 50 | selectedRelations = mv.editLayer.data.getSelectedRelations() |
| | 51 | |
| | 52 | if not(selectedRelations): |
| | 53 | JOptionPane.showMessageDialog(Main.parent, "Please select a collection relation") |
| | 54 | else: |
| | 55 | # nodetype = Node().getType() |
| | 56 | print |
| | 57 | for collection in selectedRelations: |
| | 58 | print 'COLLECTION:', collection |
| | 59 | for member in collection.getMembers(): |
| | 60 | print 'MEMBER:',member |
| | 61 | if member.isNode(): |
| | 62 | node = member.getNode() |
| | 63 | coords = node.getCoor() |
| | 64 | lon = coords.getX() |
| | 65 | lat = coords.getY() |
| | 66 | rwn_ref = node.get('rwn_ref') |
| | 67 | f.write('\t<wpt lat="' + str(lat) + '" lon="' + str(lon) + '">\n') |
| | 68 | if rwn_ref: |
| | 69 | f.write('\t\t<name>' + rwn_ref + '</name>\n') |
| | 70 | f.write('\t</wpt>\n') |
| | 71 | for member in collection.getMembers(): |
| | 72 | if member.isRelation(): |
| | 73 | routerelation = member.getRelation() |
| | 74 | f.write('\t<trk>\n') |
| | 75 | networkname = routerelation.get('network:name') |
| | 76 | if not(networkname): |
| | 77 | networkname = '' |
| | 78 | else: |
| | 79 | networkname += ' ' |
| | 80 | note = routerelation.get('note') |
| | 81 | if not(note): note = '' |
| | 82 | f.write('\t\t<name>' + networkname + note + '</name>\n') |
| | 83 | f.write('\t\t<src>OpenStreetMap.org</src>\n') |
| | 84 | f.write('\t\t<type>foot</type>\n') |
| | 85 | for routerelmember in routerelation.getMembers(): |
| | 86 | if routerelmember.isWay(): |
| | 87 | f.write('\t\t<trkseg>\n') |
| | 88 | way=routerelmember.getWay() |
| | 89 | for waynode in way.getNodes(): |
| | 90 | coords = waynode.getCoor() |
| | 91 | lon = coords.getX() |
| | 92 | lat = coords.getY() |
| | 93 | f.write('\t\t\t<trkpt lat="' + str(lat) + '" lon="' + str(lon) + '"> </trkpt>\n') |
| | 94 | |
| | 95 | f.write('\t\t</trkseg>\n') |
| | 96 | f.write('\t</trk>\n') |
| | 97 | f.write('</gpx>\n') |
| | 98 | f.close() |
| | 99 | }}} |
| | 100 | |
| | 101 | |
| | 102 | Download ontbrekende ouder-elementen voor het geselecteerde element: |
| | 103 | |
| | 104 | |
| | 105 | {{{#!python |
| | 106 | #!/bin/jython |
| | 107 | ''' |
| | 108 | |
| | 109 | This code is released under the GNU General |
| | 110 | Public License v2 or later. |
| | 111 | |
| | 112 | The GPL v3 is accessible here: |
| | 113 | http://www.gnu.org/licenses/gpl.html |
| | 114 | |
| | 115 | The GPL v2 is accessible here: |
| | 116 | http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
| | 117 | |
| | 118 | It comes with no warranty whatsoever. |
| | 119 | |
| | 120 | This code illustrates how to use Jython to: |
| | 121 | * Download all referrer for an element |
| | 122 | |
| | 123 | ''' |
| | 124 | from javax.swing import JOptionPane |
| | 125 | from org.openstreetmap.josm import Main |
| | 126 | import org.openstreetmap.josm.data.osm.Node as Node |
| | 127 | import org.openstreetmap.josm.data.osm.Way as Way |
| | 128 | import org.openstreetmap.josm.data.osm.Relation as Relation |
| | 129 | import org.openstreetmap.josm.data.osm.TagCollection as TagCollection |
| | 130 | import org.openstreetmap.josm.data.osm.DataSet as DataSet |
| | 131 | import org.openstreetmap.josm.data.osm.RelationMember as RelationMember |
| | 132 | import org.openstreetmap.josm.actions.DownloadReferrersAction as DownloadReferrersAction |
| | 133 | #import org.openstreetmap.josm.actions.downloadtasks.DownloadReferrersTask as DownloadReferrersTask; |
| | 134 | |
| | 135 | def getMapView(): |
| | 136 | if Main.main and Main.main.map: |
| | 137 | return Main.main.map.mapView |
| | 138 | else: |
| | 139 | return None |
| | 140 | |
| | 141 | mv = getMapView() |
| | 142 | if mv and mv.editLayer and mv.editLayer.data: |
| | 143 | selectedElements = mv.editLayer.data.getSelected() |
| | 144 | |
| | 145 | if not(selectedElements): |
| | 146 | JOptionPane.showMessageDialog(Main.parent, "Please select an element") |
| | 147 | else: |
| | 148 | DownloadReferrersAction.downloadReferrers(mv.editLayer, selectedElements) |
| | 149 | }}} |
| | 150 | |
| | 151 | |
| | 152 | Download ontbrekende leden van de relatie: |
| | 153 | |
| | 154 | |
| | 155 | {{{#!python |
| | 156 | #!/bin/jython |
| | 157 | ''' |
| | 158 | |
| | 159 | This code is released under the GNU General |
| | 160 | Public License v2 or later. |
| | 161 | |
| | 162 | The GPL v3 is accessible here: |
| | 163 | http://www.gnu.org/licenses/gpl.html |
| | 164 | |
| | 165 | The GPL v2 is accessible here: |
| | 166 | http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
| | 167 | |
| | 168 | It comes with no warranty whatsoever. |
| | 169 | |
| | 170 | This code illustrates how to use Jython to: |
| | 171 | * Download all missing members of a relation |
| | 172 | |
| | 173 | ''' |
| | 174 | from javax.swing import JOptionPane |
| | 175 | from org.openstreetmap.josm import Main |
| | 176 | import org.openstreetmap.josm.data.osm.Node as Node |
| | 177 | import org.openstreetmap.josm.data.osm.Way as Way |
| | 178 | import org.openstreetmap.josm.data.osm.Relation as Relation |
| | 179 | import org.openstreetmap.josm.data.osm.TagCollection as TagCollection |
| | 180 | import org.openstreetmap.josm.data.osm.DataSet as DataSet |
| | 181 | import org.openstreetmap.josm.data.osm.RelationMember as RelationMember |
| | 182 | import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask as DownloadRelationMemberTask |
| | 183 | |
| | 184 | def getMapView(): |
| | 185 | if Main.main and Main.main.map: |
| | 186 | return Main.main.map.mapView |
| | 187 | else: |
| | 188 | return None |
| | 189 | |
| | 190 | mv = getMapView() |
| | 191 | if mv and mv.editLayer and mv.editLayer.data: |
| | 192 | selectedRelations = mv.editLayer.data.getSelectedRelations() |
| | 193 | |
| | 194 | if not(selectedRelations): |
| | 195 | JOptionPane.showMessageDialog(Main.parent, "Please select a node") |
| | 196 | else: |
| | 197 | for relation in selectedRelations: |
| | 198 | if relation.hasIncompleteMembers(): |
| | 199 | #print dir(relation) |
| | 200 | print dir(DownloadRelationMemberTask) |
| | 201 | DownloadRelationMemberTask.run(DownloadRelationMemberTask(relation, relation.getIncompleteMembers(), mv.editLayer )) |
| | 202 | |
| | 203 | }}} |
| | 204 | |
| | 205 | |
| | 206 | Valideer een RCN-routerelatie: |
| | 207 | |
| | 208 | |
| | 209 | {{{#!python |
| | 210 | #!/bin/jython |
| | 211 | ''' |
| | 212 | - Validation of a rcn route relation |
| | 213 | |
| | 214 | This code is released under the GNU General |
| | 215 | Public License v2 or later. |
| | 216 | |
| | 217 | The GPL v3 is accessible here: |
| | 218 | http://www.gnu.org/licenses/gpl.html |
| | 219 | |
| | 220 | The GPL v2 is accessible here: |
| | 221 | http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
| | 222 | |
| | 223 | It comes with no warranty whatsoever. |
| | 224 | |
| | 225 | This code illustrates how to use Jython to: |
| | 226 | * loop over all members of a route relation |
| | 227 | * find out whether the member is a node, a way or a relation |
| | 228 | * add/change properties of a relation |
| | 229 | * remove properties of a relation |
| | 230 | * add members to a relation |
| | 231 | * remove members from a relation |
| | 232 | * sort all members backwards |
| | 233 | |
| | 234 | * How to set an element selected |
| | 235 | |
| | 236 | ''' |
| | 237 | from javax.swing import JOptionPane |
| | 238 | from org.openstreetmap.josm import Main |
| | 239 | import org.openstreetmap.josm.command as Command |
| | 240 | import org.openstreetmap.josm.data.osm.Node as Node |
| | 241 | import org.openstreetmap.josm.data.osm.Way as Way |
| | 242 | import org.openstreetmap.josm.data.osm.Relation as Relation |
| | 243 | import org.openstreetmap.josm.data.osm.TagCollection as TagCollection |
| | 244 | import org.openstreetmap.josm.data.osm.DataSet as DataSet |
| | 245 | import org.openstreetmap.josm.data.osm.RelationMember as RelationMember |
| | 246 | import re |
| | 247 | |
| | 248 | commandsList = [] |
| | 249 | reNumberDashNumber = re.compile(r'\d+-\d+') |
| | 250 | def getMapView(): |
| | 251 | if Main.main and Main.main.map: |
| | 252 | return Main.main.map.mapView |
| | 253 | else: |
| | 254 | return None |
| | 255 | |
| | 256 | mv = getMapView() |
| | 257 | if mv and mv.editLayer and mv.editLayer.data: |
| | 258 | dummy_relation = Relation() |
| | 259 | selectedRelations = mv.editLayer.data.getSelectedRelations() |
| | 260 | |
| | 261 | if not(selectedRelations): |
| | 262 | JOptionPane.showMessageDialog(Main.parent, "Please select a route relation") |
| | 263 | else: |
| | 264 | print |
| | 265 | for route in selectedRelations: |
| | 266 | newRelation = Relation(route) |
| | 267 | relationChanged = False |
| | 268 | name = route.get('name') |
| | 269 | if name: |
| | 270 | if reNumberDashNumber.match(name): |
| | 271 | print 'removing name when it is of the form ##-##' |
| | 272 | newRelation.remove('name') |
| | 273 | relationChanged = True |
| | 274 | else: |
| | 275 | name = '' |
| | 276 | ref = route.get('ref') |
| | 277 | if ref: |
| | 278 | if reNumberDashNumber.match(ref): |
| | 279 | print 'removing ref when it is of the form ##-##' |
| | 280 | newRelation.remove('ref') |
| | 281 | relationChanged = True |
| | 282 | else: |
| | 283 | ref = '' |
| | 284 | if relationChanged: |
| | 285 | commandsList.append(Command.ChangeCommand(route, newRelation)) |
| | 286 | |
| | 287 | Main.main.undoRedo.add(Command.SequenceCommand("Removing name and/or ref " + name + '/' + ref, commandsList)) |
| | 288 | commandsList = [] |
| | 289 | |
| | 290 | rcn_refs = []; route_relation_names = []; memberslist = [] |
| | 291 | endnodes = []; prev_endnodes = [] |
| | 292 | continuous_forward = True; continuous_backward = True |
| | 293 | prev_role = None; prev_endnodes_before_forward = None; last_endnodes_before_backward = None |
| | 294 | for member in route.getMembers(): |
| | 295 | if member.isWay(): |
| | 296 | role = member.getRole() |
| | 297 | memberslist.append(member) |
| | 298 | way = member.getWay() |
| | 299 | #JOptionPane.showMessageDialog(Main.parent, 'way is selected') |
| | 300 | endnodes = [way.getNode(0), way.getNode(way.nodesCount-1)] |
| | 301 | notfoundyet = True |
| | 302 | for endnode in endnodes: |
| | 303 | # inventorizing of rcn_ref on end nodes |
| | 304 | rcn_ref = endnode.get('rcn_ref') |
| | 305 | if rcn_ref: |
| | 306 | rcn_refs.append(int(rcn_ref)) |
| | 307 | for referrer in endnode.getReferrers(): |
| | 308 | if referrer.getType() is dummy_relation.getType(): |
| | 309 | if referrer.get('type')=='network' and referrer.get('network')=='rcn': |
| | 310 | relname=referrer.get('name') |
| | 311 | if relname: |
| | 312 | route_relation_names.append(relname) |
| | 313 | |
| | 314 | elif referrer.get('type')=='collection': |
| | 315 | route_relation_names.append('Node not assigned to network yet') |
| | 316 | # checking for continuity on ways |
| | 317 | if notfoundyet: |
| | 318 | if role: |
| | 319 | if prev_role: |
| | 320 | if role=='forward' and prev_role=='forward' and endnode in prev_endnodes: |
| | 321 | notfoundyet = False |
| | 322 | elif role=='forward' and prev_role=='backward' and endnode in last_endnodes_before_backward: |
| | 323 | notfoundyet = False |
| | 324 | elif role=='backward' and prev_role=='forward' and endnode in prev_endnodes: |
| | 325 | notfoundyet = False |
| | 326 | elif role=='backward' and prev_role=='backward' and endnode in prev_endnodes: |
| | 327 | notfoundyet = False |
| | 328 | else: |
| | 329 | if role=='forward' and endnode in prev_endnodes: |
| | 330 | notfoundyet = False |
| | 331 | elif role=='backward' and endnode in prev_endnodes: |
| | 332 | notfoundyet = False |
| | 333 | else: |
| | 334 | if prev_role: |
| | 335 | if prev_role=='forward' and endnode in prev_endnodes: |
| | 336 | notfoundyet = False |
| | 337 | elif prev_role=='backward' and endnode in last_endnodes_before_backward: |
| | 338 | notfoundyet = False |
| | 339 | else: |
| | 340 | if endnode in prev_endnodes: |
| | 341 | notfoundyet = False |
| | 342 | # Analysis of continuity of ways |
| | 343 | if prev_endnodes and notfoundyet: |
| | 344 | if role: |
| | 345 | if role == 'forward': |
| | 346 | continuous_forward = False |
| | 347 | elif role == 'backward': |
| | 348 | continuous_backward = False |
| | 349 | else: |
| | 350 | continuous_forward = False |
| | 351 | continuous_backward = False |
| | 352 | if role=='forward': |
| | 353 | if not(prev_endnodes_before_forward): |
| | 354 | prev_endnodes_before_forward = prev_endnodes |
| | 355 | elif prev_role=='forward' and role=='backward': |
| | 356 | if not(last_endnodes_before_backward): |
| | 357 | last_endnodes_before_backward = prev_endnodes |
| | 358 | elif not(role) and prev_role=='backward': |
| | 359 | prev_endnodes_before_forward = None |
| | 360 | prev_role = role |
| | 361 | prev_endnodes = endnodes |
| | 362 | # Drawing conclusions about continuity of ways |
| | 363 | if continuous_forward: |
| | 364 | print 'route is continous in the forward direction' |
| | 365 | else: |
| | 366 | print 'route is NOT CONTINUOUS in the forward direction' |
| | 367 | if continuous_backward: |
| | 368 | print 'route is continous in the backward direction' |
| | 369 | else: |
| | 370 | print 'route is NOT CONTINUOUS in the backward direction' |
| | 371 | |
| | 372 | # Drawing conclusions about rcn_refs |
| | 373 | print rcn_refs |
| | 374 | if len(rcn_refs) > 1: |
| | 375 | newRelation = Relation(route) |
| | 376 | relationChanged = False |
| | 377 | |
| | 378 | if rcn_refs[0] > rcn_refs[1]: |
| | 379 | rcn_refs.sort() |
| | 380 | print 'Flipping members order' |
| | 381 | for member in reversed(memberslist): |
| | 382 | newRelation.addMember( newRelation.getMembersCount(), member) |
| | 383 | newRelation.removeMember (0) |
| | 384 | commandsList.append(Command.ChangeCommand(route, newRelation)) |
| | 385 | Main.main.undoRedo.add(Command.SequenceCommand("Flipping order of members", commandsList)) |
| | 386 | commandsList = [] |
| | 387 | note = route.get('note') |
| | 388 | newNote = str(rcn_refs[0]).zfill(2) + '-' + str(rcn_refs[1]).zfill(2) |
| | 389 | if not(note) or note != newNote: |
| | 390 | if not(note): note = 'nothing' |
| | 391 | newRelation.put('note', newNote) |
| | 392 | relationChanged = True |
| | 393 | commandsList.append(Command.ChangeCommand(route, newRelation)) |
| | 394 | |
| | 395 | Main.main.undoRedo.add(Command.SequenceCommand("Changing note from " + note + ' to ' + newNote, commandsList)) |
| | 396 | commandsList = [] |
| | 397 | |
| | 398 | if len(route_relation_names) > 1 and route_relation_names[0] != route_relation_names[1]: |
| | 399 | print |
| | 400 | print 'This is probably a CONNECTION to another network' |
| | 401 | print route_relation_names |
| | 402 | else: |
| | 403 | print 'less than 2 end nodes with rcn_ref found' |
| | 404 | }}} |
| | 405 | |
| | 406 | [wiki:Python/RCN_Route_Validator] |
| | 407 | |
| | 408 | Extra wegen die resultaat zijn van de bewerkingen Weg splitsen van Potlatch onder relaties van Beperkingen Afslaan verwijderen |
| | 409 | |
| | 410 | {{{#!python |
| | 411 | #!/bin/jython |
| | 412 | |
| | 413 | ''' |
| | 414 | RepairTurns.py - Remove extra ways resulting from Potlatch way split operations under turn restriction relations |
| | 415 | |
| | 416 | This code is released under the GNU General |
| | 417 | Public License v2 or later. |
| | 418 | |
| | 419 | The 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 |
| | 424 | |
| | 425 | It comes with no warranty whatsoever. |
| | 426 | |
| | 427 | This 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 |
| | 428 | |
| | 429 | Only work for turn restrictions with one via node |
| | 430 | |
| | 431 | e.g. Original : from: Way1, via: Node, to:Way2 |
| | 432 | Split : from: Way1a, from: Way1b, via: Node, to: Way2 |
| | 433 | After running : from: Way1b, via: Node, to: Way2 |
| | 434 | |
| | 435 | This code illustrates how to use Jython to: |
| | 436 | * process selected items |
| | 437 | * download missing primitives in the same thread (blocking) |
| | 438 | * process, validate and remove members from relations |
| | 439 | |
| | 440 | ''' |
| | 441 | from javax.swing import JOptionPane |
| | 442 | from org.openstreetmap.josm import Main |
| | 443 | import org.openstreetmap.josm.data.osm.Node as Node |
| | 444 | import org.openstreetmap.josm.data.osm.Way as Way |
| | 445 | import org.openstreetmap.josm.data.osm.Relation as Relation |
| | 446 | import org.openstreetmap.josm.data.osm.TagCollection as TagCollection |
| | 447 | import org.openstreetmap.josm.data.osm.DataSet as DataSet |
| | 448 | import org.openstreetmap.josm.data.osm.RelationMember as RelationMember |
| | 449 | import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask as DownloadRelationMemberTask |
| | 450 | import org.openstreetmap.josm.io.MultiFetchServerObjectReader as MultiFetchServerObjectReader |
| | 451 | import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor as PleaseWaitProgressMonitor |
| | 452 | import org.openstreetmap.josm.command as Command |
| | 453 | |
| | 454 | class RestrictionError(Exception): |
| | 455 | pass |
| | 456 | |
| | 457 | def getMapView(): |
| | 458 | if Main.main and Main.main.map: |
| | 459 | return Main.main.map.mapView |
| | 460 | else: |
| | 461 | return None |
| | 462 | |
| | 463 | def getMembers (restriction): |
| | 464 | memberlist = dict() |
| | 465 | for member in restriction.getMembers(): |
| | 466 | memberRole = member.getRole() |
| | 467 | if memberRole == "via": |
| | 468 | if member.isNode() and not "via" in memberlist: |
| | 469 | memberlist[memberRole] = [member] |
| | 470 | else: |
| | 471 | raise RestrictionError, "More than one via role or via not a node" |
| | 472 | elif memberRole in ("from", "to"): |
| | 473 | if member.isWay(): |
| | 474 | try: |
| | 475 | memberlist[memberRole].append (member) |
| | 476 | except KeyError: |
| | 477 | memberlist[memberRole] = [member] |
| | 478 | else: |
| | 479 | raise RestrictionError, "From or to role not a way" |
| | 480 | else: |
| | 481 | raise RestrictionError, "Unknown role " + memberRole |
| | 482 | |
| | 483 | if len(memberlist.keys())<3: |
| | 484 | raise RestrictionError, "Some roles missing: Only " + ",".join (memberlist.keys()) + " found" |
| | 485 | return memberlist |
| | 486 | |
| | 487 | def downloadPrimitives (primitives, editlayer): |
| | 488 | """ |
| | 489 | Download a list of primitives from server, and merge into editlayer. Blocking. |
| | 490 | """ |
| | 491 | monitor = PleaseWaitProgressMonitor() |
| | 492 | monitor.showForegroundDialog() |
| | 493 | |
| | 494 | print "Downloading" |
| | 495 | try: |
| | 496 | objectReader = MultiFetchServerObjectReader().append (primitives) |
| | 497 | dataSet = objectReader.parseOsm (monitor) |
| | 498 | editlayer.mergeFrom (dataSet) |
| | 499 | editlayer.onPostDownloadFromServer() |
| | 500 | if (not objectReader.getMissingPrimitives().isEmpty()) : |
| | 501 | raise RestrictionError, "Unable to download missing primitives" |
| | 502 | print "Download completed" |
| | 503 | finally: |
| | 504 | monitor.close() |
| | 505 | |
| | 506 | def checkIfConnected (node, way, reverse): |
| | 507 | """ |
| | 508 | Return (connected, next node to compare (i.e. other end of the node) if true) |
| | 509 | """ |
| | 510 | if (way.isOneway() != 0 and reverse): |
| | 511 | return node == way.lastNode(True), way.firstNode(True) # True: auto process case whan isOneway == -1 |
| | 512 | if (way.isOneway() != 0): # not reverse |
| | 513 | return node == way.firstNode(True), way.lastNode(True) |
| | 514 | if node == way.firstNode(): |
| | 515 | return True, way.lastNode() |
| | 516 | if node == way.lastNode(): |
| | 517 | return True, way.firstNode() |
| | 518 | return False, node |
| | 519 | |
| | 520 | |
| | 521 | def repairrestriction (relation, memberlist, editLayer): |
| | 522 | """ |
| | 523 | Download missing members if needed, get list of members to remove, and remove them if no error raised during checking |
| | 524 | """ |
| | 525 | incompleteMembers = relation.getIncompleteMembers() |
| | 526 | if incompleteMembers: |
| | 527 | downloadPrimitives (incompleteMembers, editLayer); |
| | 528 | |
| | 529 | fromRemovalList = []; toRemovalList = [] |
| | 530 | |
| | 531 | if len (memberlist["from"]) >= 1: |
| | 532 | currnode = memberlist["via"][0].getNode() |
| | 533 | firstMember = True |
| | 534 | failed = False; |
| | 535 | # trace "from" members to confirm if split from one way |
| | 536 | for member in reversed(memberlist['from']): |
| | 537 | connected, currnode = checkIfConnected (currnode, member.getWay(), True) |
| | 538 | if not connected: |
| | 539 | if not firstMember: |
| | 540 | raise RestrictionError, "from ways not continuous from via node" |
| | 541 | failed = True |
| | 542 | break |
| | 543 | if not firstMember: |
| | 544 | fromRemovalList.append (member) |
| | 545 | else: |
| | 546 | firstMember = False |
| | 547 | |
| | 548 | if failed: # Second attempt in case sequence reversed when split |
| | 549 | currnode = memberlist["via"][0].getNode() |
| | 550 | for member in memberlist['from']: |
| | 551 | connected, currnode = checkIfConnected (currnode, member.getWay(), True) |
| | 552 | if not connected: |
| | 553 | raise RestrictionError, "from ways not continuous from via node" |
| | 554 | if not firstMember: |
| | 555 | fromRemovalList.append (member) |
| | 556 | else: |
| | 557 | firstMember = False |
| | 558 | |
| | 559 | if len (memberlist["to"]) >= 1: |
| | 560 | currnode = memberlist["via"][0].getNode() |
| | 561 | firstMember = True |
| | 562 | failed = False |
| | 563 | # trace "to" members to confirm if split from one way |
| | 564 | for member in memberlist['to']: |
| | 565 | connected, currnode = checkIfConnected (currnode, member.getWay(), False) |
| | 566 | if not connected: |
| | 567 | if not firstMember: |
| | 568 | raise RestrictionError, "to ways not continuous from via node" |
| | 569 | failed = True |
| | 570 | break |
| | 571 | if not firstMember: |
| | 572 | toRemovalList.append (member) |
| | 573 | else: |
| | 574 | firstMember = False |
| | 575 | |
| | 576 | if failed: # Second attempt in case sequence reversed when split |
| | 577 | currnode = memberlist["via"][0].getNode() |
| | 578 | for member in reversed(memberlist['to']): |
| | 579 | connected, currnode = checkIfConnected (currnode, member.getWay(), False) |
| | 580 | if not connected: |
| | 581 | raise RestrictionError, "to ways not continuous from via node" |
| | 582 | if not firstMember: |
| | 583 | toRemovalList.append (member) |
| | 584 | else: |
| | 585 | firstMember = False |
| | 586 | |
| | 587 | # to remove ways in fromRemovalList, toRemovalList |
| | 588 | newRelation = Relation(relation) |
| | 589 | waysToRemove = set() |
| | 590 | for removalList in [fromRemovalList, toRemovalList]: |
| | 591 | waysToRemove |= set ([m.getWay() for m in removalList]) |
| | 592 | newRelation.removeMembersFor (waysToRemove) |
| | 593 | print "Remove way(s) id:" + ",".join ([str(w.getId()) for w in waysToRemove]) |
| | 594 | return Command.ChangeCommand (relation, newRelation) |
| | 595 | |
| | 596 | |
| | 597 | validrestrictiontypes = ('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() |
| | 601 | |
| | 602 | if not(selectedRelations): |
| | 603 | JOptionPane.showMessageDialog(Main.parent, "Please select one or more relations") |
| | 604 | else: |
| | 605 | commandsList = [] |
| | 606 | for relation in selectedRelations: |
| | 607 | if relation.get('type') == "restriction" and relation.get('restriction') in validrestrictiontypes: |
| | 608 | try: |
| | 609 | memberlist = getMembers (relation) |
| | 610 | #print "".join(v * len(memberlist[v]) for v in memberlist.keys()) |
| | 611 | if (len (memberlist["from"])) > 1 or (len (memberlist["to"])) > 1 : |
| | 612 | # Repair attempt |
| | 613 | print "Attempt repair", |
| | 614 | print "relation id: " + str(relation.getId()) |
| | 615 | command = repairrestriction (relation, memberlist, mv.editLayer) |
| | 616 | print "Success" |
| | 617 | commandsList.append (command) |
| | 618 | except RestrictionError, e: |
| | 619 | print str(e), "; relation id: "+ str(relation.getId()) |
| | 620 | |
| | 621 | |
| | 622 | Main.main.undoRedo.add(Command.SequenceCommand("Repair turn restrictions", commandsList)) |
| | 623 | commandsList=[] |
| | 624 | }}} |