Python – How to Create a Polygon from a Range of Three Lat/Lon Points

latitude longitudepolygonpython

I have three lat/lon points, I need to use those in order to create a range of all possible points within the polygon that the first three create.

Test every lat/lon if it matches a condition I have (if that point creates an angle of between 50 – 150 deg with the first two points, or not).

I have my code for the condition ready.

lons = [run.gdt1[1], run.gdt2[1], run.target_area[1]]
lats = [run.gdt1[0], run.gdt2[0], run.target_area[0]]
min_lat = min(lats)
max_lat = max(lats)
self.list_a = list(arange(min_lat, max_lat, 0.01))
min_lon = min(lons)
max_lon = max(lons)
self.list_b = list(arange(min_lon, max_lon, 0.01))

if len(self.list_a) < len(self.list_b):
    self.list_b = self.list_b[: len(self.list_a)]
elif len(self.list_a) > len(self.list_b):
    self.list_a = self.list_a[: len(self.list_b)]

self.lat_lon_list = tuple(zip(self.list_a, self.list_b))
return self.lat_lon_list

What I tried to do is to create a range between the three points and check my condition (happens on another method) on every point in the new list.

My output was:

output

I realized my problem is that using the min/max to create the list, creates a list only between those two points (which I don't really understand because I figured that if a point is in the range of the other two it will create a polygon of the points).

So, how can I create a list that consists of all the points that lay between those three points? (I'm using jumps of 0.1, but if too many points will return it can be narrowed down)

My desired output is a list of all points in this triangle (gdt1, gdt2, target_area are lat/lon.

desired

Best Answer

If I wanted to generate a set of points spaced equally within the polygon, here's how I would do it using shapely (based off of this answer):

import numpy as np
from shapely.geometry import Point, Polygon

def get_evenly_spaced_points_in_polygon(poly, spacing):
    """Get a list of (lat, long) pairs spaced evenly through poly."""
    points = []
    minx, miny, maxx, maxy = poly.bounds
    for x in np.arange(minx, maxx, spacing):
        for y in np.arange(miny, maxy, spacing):
           p = Point(x, y)
           points.append((p.y, p.x) if poly.contains(p))

    return points


lons = [run.gdt1[1], run.gdt2[1], run.target_area[1]]
lats = [run.gdt1[0], run.gdt2[0], run.target_area[0]]

poly = Polygon(list(zip(lons, lats)))
spacing = 0.1  # set to whatever you want the spacing to be between points

points = get_evenly_spaced_points_in_polygon(poly, spacing)

For example, if you have three points at long/lat of (1, 5), (2, 8), and (1, 8) and use spacing=0.1:

lons = [1, 2, 1]
lats = [5, 8, 8]
poly = Polygon(list(zip(lons, lats)))
points = get_evenly_spaced_points_in_polygon(poly, spacing=0.1)

print(points)

gives

[(5.399999999999999, 1.1), (5.499999999999998, 1.1), (5.599999999999998, 1.1), (5.6999999999999975, 1.1), (5.799999999999997, 1.1), (5.899999999999997, 1.1), (5.9999999999999964, 1.1), (6.099999999999996, 1.1), (6.199999999999996, 1.1), (6.299999999999995, 1.1), (6.399999999999995, 1.1), (6.499999999999995, 1.1), (6.599999999999994, 1.1), (6.699999999999994, 1.1), (6.799999999999994, 1.1), (6.899999999999993, 1.1), (6.999999999999993, 1.1), (7.0999999999999925, 1.1), (7.199999999999992, 1.1), (7.299999999999992, 1.1), (7.3999999999999915, 1.1), (7.499999999999991, 1.1), (7.599999999999991, 1.1), (7.69999999999999, 1.1), (7.79999999999999, 1.1), (7.89999999999999, 1.1), (5.6999999999999975, 1.2000000000000002), (5.799999999999997, 1.2000000000000002), (5.899999999999997, 1.2000000000000002), (5.9999999999999964, 1.2000000000000002), (6.099999999999996, 1.2000000000000002), (6.199999999999996, 1.2000000000000002), (6.299999999999995, 1.2000000000000002), (6.399999999999995, 1.2000000000000002), (6.499999999999995, 1.2000000000000002), (6.599999999999994, 1.2000000000000002), (6.699999999999994, 1.2000000000000002), (6.799999999999994, 1.2000000000000002), (6.899999999999993, 1.2000000000000002), (6.999999999999993, 1.2000000000000002), (7.0999999999999925, 1.2000000000000002), (7.199999999999992, 1.2000000000000002), (7.299999999999992, 1.2000000000000002), (7.3999999999999915, 1.2000000000000002), (7.499999999999991, 1.2000000000000002), (7.599999999999991, 1.2000000000000002), (7.69999999999999, 1.2000000000000002), (7.79999999999999, 1.2000000000000002), (7.89999999999999, 1.2000000000000002), (5.9999999999999964, 1.3000000000000003), (6.099999999999996, 1.3000000000000003), (6.199999999999996, 1.3000000000000003), (6.299999999999995, 1.3000000000000003), (6.399999999999995, 1.3000000000000003), (6.499999999999995, 1.3000000000000003), (6.599999999999994, 1.3000000000000003), (6.699999999999994, 1.3000000000000003), (6.799999999999994, 1.3000000000000003), (6.899999999999993, 1.3000000000000003), (6.999999999999993, 1.3000000000000003), (7.0999999999999925, 1.3000000000000003), (7.199999999999992, 1.3000000000000003), (7.299999999999992, 1.3000000000000003), (7.3999999999999915, 1.3000000000000003), (7.499999999999991, 1.3000000000000003), (7.599999999999991, 1.3000000000000003), (7.69999999999999, 1.3000000000000003), (7.79999999999999, 1.3000000000000003), (7.89999999999999, 1.3000000000000003), (6.299999999999995, 1.4000000000000004), (6.399999999999995, 1.4000000000000004), (6.499999999999995, 1.4000000000000004), (6.599999999999994, 1.4000000000000004), (6.699999999999994, 1.4000000000000004), (6.799999999999994, 1.4000000000000004), (6.899999999999993, 1.4000000000000004), (6.999999999999993, 1.4000000000000004), (7.0999999999999925, 1.4000000000000004), (7.199999999999992, 1.4000000000000004), (7.299999999999992, 1.4000000000000004), (7.3999999999999915, 1.4000000000000004), (7.499999999999991, 1.4000000000000004), (7.599999999999991, 1.4000000000000004), (7.69999999999999, 1.4000000000000004), (7.79999999999999, 1.4000000000000004), (7.89999999999999, 1.4000000000000004), (6.599999999999994, 1.5000000000000004), (6.699999999999994, 1.5000000000000004), (6.799999999999994, 1.5000000000000004), (6.899999999999993, 1.5000000000000004), (6.999999999999993, 1.5000000000000004), (7.0999999999999925, 1.5000000000000004), (7.199999999999992, 1.5000000000000004), (7.299999999999992, 1.5000000000000004), (7.3999999999999915, 1.5000000000000004), (7.499999999999991, 1.5000000000000004), (7.599999999999991, 1.5000000000000004), (7.69999999999999, 1.5000000000000004), (7.79999999999999, 1.5000000000000004), (7.89999999999999, 1.5000000000000004), (6.899999999999993, 1.6000000000000005), (6.999999999999993, 1.6000000000000005), (7.0999999999999925, 1.6000000000000005), (7.199999999999992, 1.6000000000000005), (7.299999999999992, 1.6000000000000005), (7.3999999999999915, 1.6000000000000005), (7.499999999999991, 1.6000000000000005), (7.599999999999991, 1.6000000000000005), (7.69999999999999, 1.6000000000000005), (7.79999999999999, 1.6000000000000005), (7.89999999999999, 1.6000000000000005), (7.199999999999992, 1.7000000000000006), (7.299999999999992, 1.7000000000000006), (7.3999999999999915, 1.7000000000000006), (7.499999999999991, 1.7000000000000006), (7.599999999999991, 1.7000000000000006), (7.69999999999999, 1.7000000000000006), (7.79999999999999, 1.7000000000000006), (7.89999999999999, 1.7000000000000006), (7.499999999999991, 1.8000000000000007), (7.599999999999991, 1.8000000000000007), (7.69999999999999, 1.8000000000000007), (7.79999999999999, 1.8000000000000007), (7.89999999999999, 1.8000000000000007), (7.79999999999999, 1.9000000000000008), (7.89999999999999, 1.9000000000000008)]

(if you wanted, you could use numpy.round_ to prevent the annoying floating point stuff)

Related Question