def factor_polygon_into_circles(polygon, radius_km):
"""
Takes a GEOSGeomtery Polygon and a radius in kilometers. Returns a list
of (lng, lat) tuples representing the centers of circles of the specified
radius that together cover the area of the Polygon.
"""
safety_buffer = 0.01 # small safety buffer for overlap
if not isinstance(polygon, Polygon):
raise TypeError('object is not a Polygon')
if radius_km <= safety_buffer:
raise ValueError('radius must be greater than safety buffer')
# get the bounds of the polygon with a small safety buffer
buffer_dist_m = (radius_km * 1000) * safety_buffer
bounds = create_buffered_bounds(polygon, buffer_dist_m)
# get the space between circle centers, with a safety margin of 10 meters
dist_bw_centers_m = calculate_circle_spacing(radius_km * 1000, overlap_m=10)
# create a coordinate calculator for the increment distance
calculator = vincenty(meters=dist_bw_centers_m)
points = [] # array for collecting the circle centers
# position first point so the circle intersects with the sw corner of bounds
starting_pt = vincenty(kilometers=radius_km).destination(
point=(bounds.s_lat, bounds.w_lng),
bearing=45
)
# get the starting latitude
lat = starting_pt.latitude
# find the number of rows of circles needed to span the height of the polygon
rows = int(math.ceil(bounds.height_m / dist_bw_centers_m))
for dummy_row_idx in range(rows):
# reset the starting longitude before each west-to-east loop
lng = starting_pt.longitude
# get the distance between w_lng and e_lng at the current latitude
width_m = bounds.get_width_at_latitude_m(lat)
# find the number of columns of circles needed to span the width
cols = int(math.ceil(width_m / dist_bw_centers_m))
for dummy_col_idx in range(cols):
# add current coordinates to point array
points.append((lng, lat))
# calculate next point to the east and increment longitude
lng = calculator.destination(point=(lat, lng), bearing=90).longitude
# calculate next point to the north and increment latitude
lat = calculator.destination(point=(lat, lng), bearing=0).latitude
return points
评论列表
文章目录