PyQGIS Geocoding – How to Geocode Address in Attribute Table with PyQGIS

attribute-tablefeaturesfields-attributesgeocodingpyqgis

The script doesn't work as if I wanted.

from qgis.core import *
from .resources import *
import json

mylayer = QgsProject.instance().mapLayersByName("layer")[0]
features = mylayer.getFeatures()
for f in features:  
 dane1 = f.attribute(2)
        
url = 'https://nominatim.openstreetmap.org/?addressdetails=1&&format=json&limit=1&q='+dane1

response = requests.get(url)
    
aaa = json.dumps(response.json()[0]["lat"], ensure_ascii=False, indent=4)
bbb = json.dumps(response.json()[0]["lon"], ensure_ascii=False, indent=4)

material = aaa.replace('"','') + ', ' + bbb.replace('"','')
                   
mylayer.startEditing()

forum = [material]
i = 0

for seg in mylayer.getFeatures():
    seg['WSP_X'] = forum[i]
    i += 1
    mylayer.updateFeature(seg)
    mylayer.commitChanges()

Effect:

enter image description here

Desired effect:

enter image description here

Script doesn't work correctly.

Best Answer

The main issue is that you are making the Nominatim request only once. It does not get updated and re-sent for each feature. There are a couple of other issues too, see my comments in the code for explanation.

from qgis.core import *
from .resources import *
import requests
import json

mylayer = QgsProject.instance().mapLayersByName("layer")[0]
features = mylayer.getFeatures()

# open the edit session outside the loop
mylayer.startEditing()

for f in features:  
    dane1 = f.attribute(2)
    
    # move the URL formulation and Nominatim request inside the loop to ensure the URL is upated with each new address
    url = 'https://nominatim.openstreetmap.org/?addressdetails=1&&format=json&limit=1&q='+dane1

    # send request once for every feature
    response = requests.get(url)
    
    aaa = json.dumps(response.json()[0]["lat"], ensure_ascii=False, indent=4)
    bbb = json.dumps(response.json()[0]["lon"], ensure_ascii=False, indent=4)

    material = aaa.replace('"','') + ', ' + bbb.replace('"','')

    # remove the `forum` variable and work directly with the `material` variable
    #forum = [material]
    
    # no need to get the features again because you are already iterating through them
    
    # corrected the field name and use the `f` variable from the original feature iterator, rather than `seg`
    f['WSP_X_Y'] = material
    mylayer.updateFeature(f)

mylayer.commitChanges()

enter image description here

Related Question