# Python, create a polygon from range of three lat/lon points

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:

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.

• Could you please add a sketch of what you would like to get. Commented Dec 27, 2019 at 19:48
• @IanTurton added. Commented Dec 27, 2019 at 20:05
• looks like your immediate problem is @ self.lat_lon_list = tuple(zip(self.list_a, self.list_b)). You'll only get as many lat/lon pairs as there are elements in each list (1st lat combined w 1st lon, 2nd w/ 2nd, etc). It sounds like what you really want is a grid of all possible combos of each lat and lon in your two lists. stackoverflow.com/questions/12935194/… might put you in the right direction
– Nick
Commented Dec 27, 2019 at 21:14

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)

• This is a great way too, though a conversion to x,y coordinates is needed, but better than mine if you will want to develop your data into geopandas and such. Commented Jan 3, 2020 at 16:16

I ended up using itertools

``````
lons = [run.gdt1[1], run.gdt2[1], run.uav[1]]
lats = [run.gdt1[0], run.gdt2[0], run.uav[0]]
min_lat = min(lats)
max_lat = max(lats)
self.list_a = list(np.arange(min_lat, max_lat, 0.01))
min_lon = min(lons)
max_lon = max(lons)
self.list_b = list(np.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)]

before_itertools_list = [self.list_a, self.list_b]
lat_lon_list = list(itertools.product(*before_itertools_list))
self.lat_lon_list = [list(elem) for elem in lat_lon_list]
return self.lat_lon_list
``````