3

I want to calculate the sum of the inverse distances from one main point to multiple other points within a buffer around the main point in QGIS

I have a point file with multiple home addresses (red points). I have another point file with restaurant locations (blue points). For each home address I want to calculate the sum of the inverse Euclidian distance from the home address to all the restaurants within the neighbourhood (n=all restaurants in 500m buffer). The 500m buffers are often overlapping. enter image description here

enter image description here

Is it possible to do this calculation in QGIS?

6
  • 1
    So, for each adress you want to sum up the distance to all restaurants within 500 m distance? And then you want to do ... what?
    – Erik
    Commented Oct 26, 2023 at 11:32
  • Sorry, i was not clear, i will adjust my wording.. For each address I want to sum up the inverse distance to all restaurants.
    – Anouk
    Commented Oct 26, 2023 at 11:46
  • 2
    Please provide an example, I have no idea how this value should be calculated and what end it serves.
    – Erik
    Commented Oct 26, 2023 at 11:49
  • I added an example. I want to use this measure to account for both proximity and availability of restaurants. I sum the inverse distances because restaurant closer to home have more influence than points farther away.
    – Anouk
    Commented Oct 26, 2023 at 12:06
  • 1
    what do you mean by 'inverse distance'? There are some tools that leverage IDW such as Moran's I but it isn't clear if this is what you want. see en.wikipedia.org/wiki/Inverse_distance_weighting
    – Kartograaf
    Commented Oct 26, 2023 at 12:20

2 Answers 2

1

Use this expression with Field Calculator to get 1) an array of all distances to all points on the layer restaurant_layer within max. 900 m (change this value to fit your needs) from each address, then 2) divide 1 by each of the distances and 3) sum up all these values:

array_sum(
    array_foreach (
        overlay_nearest ('restaurant_layer', $geometry, max_distance:=900, limit:=-1),
        1 / distance ($geometry, @element)
    )
)
2
  • Nice and neat. Provided pyqgis solution as well but this is better.
    – Kartograaf
    Commented Oct 26, 2023 at 15:55
  • 1
    Thank you! This was exactly what I was looking for!
    – Anouk
    Commented Oct 30, 2023 at 8:17
0

Here is a pyqgis recipe that will take in points files with centroids (home addresses) and points (restaurants) and a buffer distance, compute the inverse distances and sum them, then write the result as a new file.

Keep in mind the units are tied to the CRS. This example uses decimal degrees (EPSG:4326).


import processing

#specify the buffer size in map units
bdist = 0.45

#specify paths to data
centpath = "C:/path/to/input/centroids.gpkg"
pointpath = "C:/path/to/input/points.gpkg"

#read in data
centroid_layer = QgsVectorLayer(centpath, "centroids", "ogr")
point_layer = QgsVectorLayer(pointpath, "points", "ogr")

#get centroid features
cent_features = centroid_layer.getFeatures()

#add new field for inverse distances if one does not exist
if centroid_layer.dataProvider().fieldNameIndex("sum_inv_dist") == -1:
    centroid_layer.dataProvider().addAttributes([QgsField("sum_inv_dist", QVariant.Double)])
    centroid_layer.updateFields()

#iterate through centroids
for idx, cent in enumerate(cent_features): 
    
    #get point features
    point_features = point_layer.getFeatures()
    
    #initialize sum inverse distance variable
    inv_dist_sum = 0
    
    #buffer centroid point
    buff = cent.geometry().buffer(bdist, 5)
    
    #iterate through points
    for index, point in enumerate(point_features):
        
        #get feature geometry
        pointgeom = point.geometry()
        
        #check if point fall within buffer
        if pointgeom.within(buff):
            
            #Create a measure object
            distance = QgsDistanceArea()
            
            #calculate inverse distance between points
            invdist = 1 / (distance.measureLine([pointgeom.asPoint(),cent.geometry().asPoint()]))
            
            #add inverse distance to sum variable
            inv_dist_sum = inv_dist_sum + invdist
    
    #get column nubmer of new column
    col_id = centroid_layer.dataProvider().fieldNameIndex("sum_inv_dist")
    
    #append inverse distance to layer
    centroid_layer.startEditing()
    centroid_layer.changeAttributeValue(cent.id(), col_id, inv_dist_sum)
    centroid_layer.commitChanges()
    
#write out result
params = {'INPUT': centroid_layer,
        'OUTPUT': 'C:/Path/to/output/points_distances.gpkg',
        'LAYER_NAME': 'points_distances'}
          
processing.run("native:savefeatures", params)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.