# Prototype Solar Mini Grid Layout (1st Implementation)

 Pay Notebook Creator: Roy Hyunjin Han 250 Set Container: Numerical CPU with TINY Memory for 10 Minutes 0 Total 0

# Vision¶

Inspire a community of professionals skilled in spatiotemporal analysis for community health and safety.

# Mission¶

Prototype an algorithm that places batteries near service drop poles.

Roy Hyunjin Han

# Context¶

A battery must be close enough to its discharge point to minimize distribution loss.

# Timeframe¶

20171108-2000 - 20171108-2100: 60 minutes estimated

# Objectives¶

1. Draft algorithm.
2. Prototype tool.

# Log¶

20171108-2000 - 20171108-2030: 30 minutes

This seems to be identical to the problem of placing service drop poles near customers. The difference is that there is no limit to the number of poles per battery.

In [1]:
from shapely.geometry import MultiPoint, Point

drop_poles = [
Point(1, 1),
Point(3, 2),
Point(7, 0),
]
MultiPoint(drop_poles)

Out[1]:
<shapely.geometry.multipoint.MultiPoint at 0x7f6490ccd550>
In [2]:
from shapely.geometry import GeometryCollection, Polygon

obstacle_geometries = [
Polygon([(1.5, 0), (1.5, 3), (2.5, 3), (2.5, 0)])
]
GeometryCollection(drop_poles + obstacle_geometries)

Out[2]:
<shapely.geometry.collection.GeometryCollection at 0x7f64951c4550>
+ Create a sample dataset of service drop poles
+ Create example obstacles



20171110-1330 - 20171110-1400: 30 minutes

Remember that the first implementation only considers the case of no roads and no obstacles.

In [3]:
from copy import copy
from shapely.geometry import LineString
from shapely.ops import polygonize, unary_union

def get_source_geometries(target_geometries, maximum_distance):
# Convert target_geometries into target_polygons using maximum_distance
target_polygons = [x.buffer(maximum_distance) for x in target_geometries]
lonely_polygons = copy(target_polygons)
# Identify areas of intersection
social_polygons = []
for polygon in get_disjoint_polygons(target_polygons):
connected_polygons = []
for target_polygon in target_polygons:
if target_polygon.contains(polygon.centroid):
connected_polygons.append(target_polygon)
if len(connected_polygons) > 1:
for target_polygon in connected_polygons:
try:
lonely_polygons.remove(target_polygon)
except ValueError:
pass
social_polygons.append(polygon)
polygon.connected_polygons = connected_polygons
# Define connected_polygons for each lonely_polygon
for polygon in lonely_polygons:
polygon.connected_polygons = []
return social_polygons + lonely_polygons

def get_disjoint_polygons(overlapping_polygons):
'Split overlapping polygons into disjoint polygons'
rings = [LineString(list(
x.exterior.coords)) for x in overlapping_polygons]
return list(polygonize(unary_union(rings)))

In [4]:
GeometryCollection(drop_poles + get_source_geometries(drop_poles, 1))

Out[4]:
<shapely.geometry.collection.GeometryCollection at 0x7f64792a1b00>
In [5]:
GeometryCollection(drop_poles + get_source_geometries(drop_poles, 1.5))

Out[5]:
<shapely.geometry.collection.GeometryCollection at 0x7f64915b7c88>
+ Minimize the distance of a battery to each service drop pole
+ Minimize the number of batteries
+ Limit the maximum distance of a battery to a service drop pole



We'll save obstacles for the 3rd implementation.

20171117-1845 - 20171117-1900: 15 minutes

It seems that each of the batteries are supposed to be placed on a distribution line and distances to each service drop are computed as measured along the distribution line. We'll save that for the 2nd implementation.

Do not put a battery inside a passable obstacle or unpassable obstacle