5

I need to find distance in eastward direction from each point to the closest polygon edge:

enter image description here

I can find shortest distance in any direction with:

pointlayer = QgsProject.instance().mapLayersByName('points_inter_squares')[0]
points = [[f.geometry(),f['Ruta_100km']] for f in pointlayer.getFeatures()]

squarelayer = QgsProject.instance().mapLayersByName('squares')[0]
squares = [[f.geometry(),f['Ruta_100km']] for f in squarelayer.getFeatures()]

for point in points:
    print(min([QgsGeometry.distance(point[0],square[0]) for square in squares if point[1]!=square[1]]))

>>12639.380321901293
>>3320.150455611874
>>6650.862023710273
>>2452.079442886869

'Ruta_100km' is the Squares IDs, so I measure distance to all Squares but the one intersecting the Points.

Is there a method where I can specify direction when measuring distance?

4
  • 1
    You could extend a line from your points in an eastward direction and intersect with the grid, find the segment that touches your creation point and get that segments' length. The eastward segment should be a very large distance to ensure that there is an intersection.. find the extent of your grid and use the maximum X value. Commented Dec 10, 2018 at 8:12
  • Is the side length of the squares always 100km and the origin coordinates of the grid an integer multiple of 100km or are you looking for a general solution? Commented Dec 10, 2018 at 8:12
  • The grid is not always 100 km, but always a square grid.
    – Bera
    Commented Dec 10, 2018 at 8:21
  • @Michael Stimson: Isn't there always an intersection if the length of your proposed eastward line equals the grid spacing and the point is not exactly on a grid line? Commented Dec 10, 2018 at 9:15

2 Answers 2

5

A general solution: Provided a grid described by its origin (x0, y0) and a grid spacing d_grid (100km in your example), the problem reduces to calculate the difference between the test points p = (x, y) x-coordinate and the x-coordinate of the N-S grid line lying next to p, x_square, so the question is, what is x_square:

enter image description here

The following does not need a grid layer, but only the description of the grid as described above:

for p in points:
    # assumption: grid origin (x0, y0), spacing d_grid
    # metric coordinate system
    y = p.geometry().asPoint().x()
    # calculate y-distance to origin
    dx0 = x - x0
    # calculate number of square in which p(x, y) lies (2 in the example)
    square_count = int(dx0 / d_grid) + 1
    # calculate x-coordinate of N-S grid line next to p
    x_square = x0 + d_grid * square_count
    # calculate the desired distance
    dp = x_square - x
    print(dp)
4

Based on the comment from @Michael Stimson I managed to solve this by creating a line extending east, intersecting this with the polygons, finding min x coord of the resulting line(s) and subtracting this minx-startx. It should also work with irregular shaped polygons. It requires having polygon ids on the points (for example by intersecting them) to exclude any polygon directly intersecting the point.

pointlayer = QgsProject.instance().mapLayersByName('points_inter_squares')[0]
points = [[f.geometry(),f['Ruta_100km']] for f in pointlayer.getFeatures()]

squarelayer = QgsProject.instance().mapLayersByName('squares')[0]
squares = [[f.geometry(),f['Ruta_100km']] for f in squarelayer.getFeatures()]

max_search_distance = 200000

for geom, pointid in points:
    startx, starty = geom.asMultiPoint()[0]
    endx = startx+max_search_distance
    line = QgsGeometry.fromPolyline([QgsPoint(startx,starty), QgsPoint(startx+max_search_distance,starty)])
    intersections = [QgsGeometry.intersection(line,square[0]) for square in squares if (pointid!=square[1] and QgsGeometry.intersects(line,square[0]))]
    minx = min([l.asPolyline()[0][0] for l in intersections], default=startx) #If no feature is found, set minx to startx which will give 0 distance when subtracting
    print(minx-startx)

enter image description here

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.