Prerequisites for Routing with OSM: Coordinates
Before we will have a look on the routing and getting the web response from OSM into QGIS we need to translate our start and end locations/addresses into coordinates. If you have point features you can simply add the geometry to the attribute table: Of course you also have access to the point coordinates using the PyQGIS commands:pl=qgis.utils.iface.activeLayer() #for your activated point shapefile iterator = pl.getFeatures() for feature in iterator: geom = feature.geometry() print geom.asPoint()
Routing with and Import from OSM
The University of Heidelberg owns a great routing platform. Furthermore they have an API for this nice little tool which is well described on the OSM wiki. We will use this API. The API will respond a XML document which then will be parsed into a line shapefile. So let’s start:First let’s get the response into the Python console. We will start with the route from Oedheim (Germany) to Modautal. The above described solutions will give us the coordinates from the start and end point or our route:
Oedheim 9.256506 49.240011 Modautal 8.72083 49.7606We can use this coordinates already in the browser and open the following URL:
http://openls.geog.uni-heidelberg.de/testing2015/route?Start=9.256506,49.240011&End=8.72083,49.7606&Via=&lang=de&distunit=KM&routepref=Fastest&avoidAreas=&useTMC=false&noMotorways=false&noTollways=false&instructions=falseHow to do this in Python? We will use the requests module for getting the request and the build-in xml parser xml:
import requests from xml.etree import ElementTree url="http://openls.geog.uni-heidelberg.de/testing2015/route?Start=9.256506,49.240011&End=8.72083,49.7606&Via=&lang=de&distunit=KM&routepref=Fastest&avoidAreas=&useTMC=false&noMotorways=false&noTollways=false&instructions=false" response = requests.get(url) xml = ElementTree.fromstring(response.content)Now we just need to analyze the structure (take a look at the response in your browser) and we need to know that this sentence from the Etree documentation:
Children are nested, and we can access specific child nodes by index: root[0][1].textKeeping this in mind we can easily iterate over the point coordinates of the route and add them as vertices of a line shapefile:
from PyQt4.QtCore import QVariant layer = QgsVectorLayer('LineString', 'route_OSM', "memory") pr = layer.dataProvider() pr.addAttributes([QgsField("attribution", QVariant.String)]) layer.updateFields() fet = QgsFeature() seg=[] for i in range(0,len(xml[1][0][1][0])): seg.append(QgsPoint(float(str.split(xml[1][0][1][0][i].text)[0]),float(str.split(xml[1][0][1][0][i].text)[1]))) fet.setGeometry(QgsGeometry.fromPolyline(seg)) fet.setAttributes(["route provided by openrouteservice.org"]) pr.addFeatures([fet]) layer.updateExtents() #update it QgsMapLayerRegistry.instance().addMapLayer(layer)And now let’s compare: Unfortunately we can’t rely on this project from the University Heidelberg:
Description: Through the OpenLS interface requests can be generated to the appropriate services without further query limitations. The offered API’s are only valid for ‘ one ‘ year. In case you plan a long-term use of the interfaces within your projects or high volume or for commercial applications , please contact openrouteservice AT geog.uni-heidelberg.deNevertheless: Download the example and alter it according to your needs.
Unfortunately Openrouteservice is disabled for North America…