base_network: Improve assignment of countries

This commit is contained in:
Jonas Hörsch 2018-10-26 16:08:50 +02:00
parent 98b3ef5e20
commit c0fe95a31d

View File

@ -7,13 +7,12 @@ import numpy as np
import scipy as sp, scipy.spatial import scipy as sp, scipy.spatial
from scipy.sparse import csgraph from scipy.sparse import csgraph
from six import iteritems from six import iteritems
from six.moves import filter
from itertools import product from itertools import product
from shapely.geometry import Point, LineString from shapely.geometry import Point, LineString
import shapely, shapely.prepared, shapely.wkt import shapely, shapely.prepared, shapely.wkt
from vresutils.graph import BreadthFirstLevels import networkx as nx
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -23,6 +22,9 @@ import pypsa
def _get_oid(df): def _get_oid(df):
return df.tags.str.extract('"oid"=>"(\d+)"', expand=False) return df.tags.str.extract('"oid"=>"(\d+)"', expand=False)
def _get_country(df):
return df.tags.str.extract('"country"=>"([A-Z]{2})"', expand=False)
def _find_closest_links(links, new_links, distance_upper_bound=1.5): def _find_closest_links(links, new_links, distance_upper_bound=1.5):
tree = sp.spatial.KDTree(np.vstack([ tree = sp.spatial.KDTree(np.vstack([
new_links[['x1', 'y1', 'x2', 'y2']], new_links[['x1', 'y1', 'x2', 'y2']],
@ -320,14 +322,30 @@ def _set_countries_and_substations(n):
buses['substation_lv'] = lv_b & onshore_b & (~ buses['under_construction']) & has_connections_b buses['substation_lv'] = lv_b & onshore_b & (~ buses['under_construction']) & has_connections_b
buses['substation_off'] = (offshore_b | (hv_b & onshore_b)) & (~ buses['under_construction']) buses['substation_off'] = (offshore_b | (hv_b & onshore_b)) & (~ buses['under_construction'])
# Nearest country in numbers of hops defines country of homeless buses
c_nan_b = buses.country.isnull() c_nan_b = buses.country.isnull()
c = n.buses['country'] if c_nan_b.sum() > 0:
graph = n.graph() c_tag = _get_country(buses.loc[c_nan_b])
n.buses.loc[c_nan_b, 'country'] = \ c_tag.loc[c_tag.index.difference(countries)] = np.nan
[(next(filter(len, map(lambda x: c.loc[x].dropna(), BreadthFirstLevels(graph, [b])))) n.buses.loc[c_nan_b, 'country'] = c_tag
.value_counts().index[0])
for b in buses.index[c_nan_b]] c_tag_nan_b = n.buses.country.isnull()
# Nearest country in path length defines country of still homeless buses
# Work-around until commit 705119 lands in pypsa release
n.transformers['length'] = 0.
graph = n.graph(weight='length')
n.transformers.drop('length', axis=1, inplace=True)
for b in n.buses.index[c_tag_nan_b]:
df = (pd.DataFrame(dict(pathlength=nx.single_source_dijkstra_path_length(graph, b, cutoff=200)))
.join(n.buses.country).dropna())
assert not df.empty, "No buses with defined country within 200km of bus `{}`".format(b)
n.buses.at[b, 'country'] = df.loc[df.pathlength.idxmin(), 'country']
logger.warning("{} buses are not in any country or offshore shape,"
" {} have been assigned from the tag of the entsoe map,"
" the rest from the next bus in terms of pathlength."
.format(c_nan_b.sum(), c_nan_b.sum() - c_tag_nan_b.sum()))
return buses return buses