Accessing xServer internet from Python
-
This section explains how to request xLocateServer with python inside QGIS. The result of the request will be displayed as a layer on the map.
Add Python HTTP Requests to QGIS
-
The xServer python script uses the requests extension to call xServer internet. You can get it from the GitHub repository https://github.com/kennethreitz/requests
Just download it and add the folder requests to the QGIS Python folder, e.g. C:\Program Files\QGIS Brighton\apps\Python27
-
Add the script to the processing toolbox
-
You can start a script within QGIS by adding a .py file to the processing toolbox.
- Paste the script code below to a file named xlocate_findaddress.py
- Copy the file to the folder <User Folder>\.qgis2\processing\scripts
- Open the processing toolbox under Processing->Toolbox
- Now you can start the script by double-clicking on the item Scripts->[PTV scripts]->xlocate_findaddress in the tree.
-
Run the script and validate the result
-
Enter your token into the dialog, set the address and press Run. A new layer output_geoc is added to the map. The layer displays the result locations of the geocoding. You can also open the result as a table by right-clicking on the layer and opening the attribute table.
-
#a simple geocoding request that displays the result as a QGIS layer
##[PTV scripts]=group
##cluster=string eu-n-test
##token=string enter your token here
##country=string
##address=string Neustadt
##output_geoc=output vector
import fileinput
import sys, os, json, requests
from PyQt4.QtCore import *
from qgis.core import *
from qgis.utils import *
from requests.auth import HTTPBasicAuth
# our geocoding function
def findAddressByText(url, token, country, address):
header = {'content-type': 'application/json'}
request = { "address": address,
"country": country,
"options": [],
"sorting": [],
"additionalFields": [],
"callerContext": {
"properties": [{"key": "CoordFormat","value": "OG_GEODECIMAL"},{"key": "Profile","value": "default"},{"key": "ResponseGeometry", "value": "WKT"}
]}
}
jsondata = json.dumps(request)
jsonresp = requests.post(url = url, data = jsondata, headers = header, auth = HTTPBasicAuth('xtok', token))
if jsonresp.status_code == 200:
pyresp = json.loads(jsonresp.text)
jsonresponse = pyresp["resultList"]
return jsonresponse
else:
raise Exception("Web error " + str(jsonresp.status_code))
# build url
url = "https://xlocate-" + cluster + ".cloud.ptvgroup.com/xlocate/rs/XLocate/findAddressByText"
# invoke the geocoding
jsonresponse = findAddressByText(url, token, country, address)
# build the fields collection
fields = QgsFields() # 2: Integer 6: Float 10: String
fields.append(QgsField("id", 2,"Integer"))
fields.append(QgsField("country", 10, "String", 32))
fields.append(QgsField("state", 10,"String", 128))
fields.append(QgsField("postcode", 10,"String", 12))
fields.append(QgsField("city", 10,"String", 128))
fields.append(QgsField("city2", 10,"String", 128))
fields.append(QgsField("street", 10,"String", 128))
fields.append(QgsField("houseNumber", 10,"String", 32))
fields.append(QgsField("adminRegion", 10,"String", 128))
fields.append(QgsField("totalScore", 2,"Integer"))
# create the output layer
outputLayer = QgsVectorFileWriter(output_geoc, None, fields, QGis.WKBPoint,QgsCoordinateReferenceSystem(4326))
# fill the layer data
count=0
for resultList in jsonresponse:
count+=1
country=resultList["country"]
state=resultList["state"]
postcode=resultList["postCode"]
city=resultList["city"]
city2=resultList["city2"]
street=resultList["street"]
housenumber=resultList["houseNumber"]
score=resultList["totalScore"]
adminRegion=resultList["adminRegion"]
geomwkt=resultList["coordinates"]["wkt"]
outFeat = QgsFeature()
outFeat.setGeometry(QgsGeometry.fromWkt(geomwkt))
outFeat.setAttributes([count, country, state, postcode, city, city2, street, housenumber, adminRegion, score])
outputLayer.addFeature(outFeat)
progress.setText("Geocoding matches: " + str(count))
progress.setText("---------------------------------------")
del outputLayer