Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Release notes

## Unversioned (2026-05-19)

### Adjustments

* If coordinates have not been saved to a design file for the nodes under an `Area`, they are now placed *symmetrically* around the circle (that is, accounting for one node being the `GeoAvailability` node to be placed at the center).
* The default value for the radius of the circle for placing nodes without coordinates is now a third of the minimal distance between area coordinates defined in the `top_level` design file.

## Version 0.7.1 (2026-04-24)

### Bugfix
Expand Down
Binary file modified docs/src/figures/EMI_geography.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/src/figures/EMI_geography_Oslo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 40 additions & 18 deletions src/setup_topology.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,42 @@ function EnergySystemDesign(
Dict()
end

# Complete the `id_to_color_map` if some products are lacking (this is done by choosing
# colors for the lacking `Resource`s that are most distinct to the existing set of colors)
if !issubset(get_products(system), keys(id_to_color_map))
id_to_color_map = set_colors(get_products(system), id_to_color_map)
end

# Initialize components and connections
components = EnergySystemDesign[]
connections = Connection[]

# Create an iterator for the current system
elements = get_children(system)

# Calculate radius for node placement if system is a SystemGeo (i.e. contains geographical information)
if isa(system, SystemGeo)
# Collect all (lon, lat) coordinates from elements that have them
coords = [
Point2f(element.lon, element.lat)
for element ∈ get_children(system)
]
coordinates_missing = false
coords = Point2f[]
for element ∈ elements
# Extract available information from file (stored in the `design_dict` variable)
key::String = string(element)
system_info::Dict = haskey(design_dict, key) ? design_dict[key] : Dict()
if haskey(system_info, "x") && haskey(system_info, "y")
xy = Point2f(system_info["x"], system_info["y"])
push!(coords, xy)
else
coordinates_missing = true
break
end
end
if coordinates_missing
# Collect all (lon, lat) coordinates from elements that have them
coords = [
Point2f(element.lon, element.lat)
for element ∈ get_children(system)
]
end

# Compute all pairwise distances
min_dist = Inf
Expand All @@ -66,19 +96,6 @@ function EnergySystemDesign(
radius = min_dist / 3
end

# Complete the `id_to_color_map` if some products are lacking (this is done by choosing
# colors for the lacking `Resource`s that are most distinct to the existing set of colors)
if !issubset(get_products(system), keys(id_to_color_map))
id_to_color_map = set_colors(get_products(system), id_to_color_map)
end

# Initialize components and connections
components = EnergySystemDesign[]
connections = Connection[]

# Create an iterator for the current system
elements = get_children(system)

design = EnergySystemDesign(
system,
id_to_color_map,
Expand All @@ -99,6 +116,11 @@ function EnergySystemDesign(
if !isnothing(elements)
current_node::Int64 = 1
nodes_count = length(get_children(system))
if !isa(parent, NothingDesign) && isa(get_system(parent), SystemGeo)
# If the parent is a SystemGeo, we subtract one to the nodes count to account
# for the availability node that is placed in the center
nodes_count -= 1
end

# Loop through all components of `system`
for element ∈ elements
Expand Down
4 changes: 2 additions & 2 deletions src/utils_gen/structures_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ function installed()
end

"""
place_nodes_in_circle(total_nodes::Int64, current_node::Int64, r::Float32, c::Point2f)
place_nodes_in_circle(n::Int64, i::Int64, r::Float32, c::Point2f)
Return coordinate for point number `i` of a total of `n` points evenly distributed around
a circle of radius `r` centered at `c` from -π/4 to 5π/4.
"""
function place_nodes_in_circle(n::Int64, i::Int64, r::Float32, c::Point2f)
θ::Float32 = n == 1 ? π32 : -π32 / 4 + 32 / 2 * (1 - (i - 1) / (n - 1))
θ::Float32 = n == 1 ? π32 : -π32 / 4 + 32 / 2 * (1 - Float32(i - 1) / Float32(n - 1))
return c + r * Point2f(cos(θ), sin(θ))
end

Expand Down
Loading