Finding distance between point and polygon edge in eastward direction using PyQGIS?











up vote
4
down vote

favorite












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?










share|improve this question




















  • 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.
    – Michael Stimson
    20 hours ago












  • 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?
    – Jochen Schwarze
    20 hours ago










  • The grid is not always 100 km, but always a square grid.
    – BERA
    20 hours ago










  • @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?
    – Jochen Schwarze
    19 hours ago















up vote
4
down vote

favorite












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?










share|improve this question




















  • 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.
    – Michael Stimson
    20 hours ago












  • 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?
    – Jochen Schwarze
    20 hours ago










  • The grid is not always 100 km, but always a square grid.
    – BERA
    20 hours ago










  • @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?
    – Jochen Schwarze
    19 hours ago













up vote
4
down vote

favorite









up vote
4
down vote

favorite











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?










share|improve this question















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?







pyqgis distance






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 18 hours ago

























asked 20 hours ago









BERA

14.1k51839




14.1k51839








  • 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.
    – Michael Stimson
    20 hours ago












  • 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?
    – Jochen Schwarze
    20 hours ago










  • The grid is not always 100 km, but always a square grid.
    – BERA
    20 hours ago










  • @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?
    – Jochen Schwarze
    19 hours ago














  • 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.
    – Michael Stimson
    20 hours ago












  • 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?
    – Jochen Schwarze
    20 hours ago










  • The grid is not always 100 km, but always a square grid.
    – BERA
    20 hours ago










  • @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?
    – Jochen Schwarze
    19 hours ago








1




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.
– Michael Stimson
20 hours ago






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.
– Michael Stimson
20 hours ago














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?
– Jochen Schwarze
20 hours ago




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?
– Jochen Schwarze
20 hours ago












The grid is not always 100 km, but always a square grid.
– BERA
20 hours ago




The grid is not always 100 km, but always a square grid.
– BERA
20 hours ago












@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?
– Jochen Schwarze
19 hours ago




@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?
– Jochen Schwarze
19 hours ago










2 Answers
2






active

oldest

votes

















up vote
5
down vote













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)





share|improve this answer






























    up vote
    4
    down vote













    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






    share|improve this answer























      Your Answer








      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "79"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fgis.stackexchange.com%2fquestions%2f305515%2ffinding-distance-between-point-and-polygon-edge-in-eastward-direction-using-pyqg%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      5
      down vote













      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)





      share|improve this answer



























        up vote
        5
        down vote













        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)





        share|improve this answer

























          up vote
          5
          down vote










          up vote
          5
          down vote









          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)





          share|improve this answer














          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)






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 13 hours ago

























          answered 19 hours ago









          Jochen Schwarze

          6,15531454




          6,15531454
























              up vote
              4
              down vote













              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






              share|improve this answer



























                up vote
                4
                down vote













                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






                share|improve this answer

























                  up vote
                  4
                  down vote










                  up vote
                  4
                  down vote









                  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






                  share|improve this answer














                  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







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 13 hours ago

























                  answered 13 hours ago









                  BERA

                  14.1k51839




                  14.1k51839






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Geographic Information Systems Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fgis.stackexchange.com%2fquestions%2f305515%2ffinding-distance-between-point-and-polygon-edge-in-eastward-direction-using-pyqg%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Morgemoulin

                      Scott Moir

                      Souastre