Prototype Solar Mini Grid Layout (1st Implementation)




Pay Notebook Creator: Roy Hyunjin Han250
Set Container: Numerical CPU with TINY Memory for 10 Minutes 0
Total0

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.

Owner

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.

Tasks

Now

Future

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