Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spatial Aggregations V2 #4627

Merged
merged 14 commits into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from 13 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
92 changes: 88 additions & 4 deletions config/exchanges.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@
},
"rotation": -140
},
"AT->IT": {
"lonlat": [12.344464, 46.741723],
"rotation": -140
},
"AT->SI": {
"lonlat": [15.014142, 46.613582],
"parsers": {
Expand Down Expand Up @@ -169,6 +173,11 @@
},
"rotation": -130
},
"AX->SE": {
"capacity": [-80, 80],
"lonlat": [19.239, 60.063],
"rotation": -130
},
"AZ->GE": {
"lonlat": [45.153, 41.398],
"parsers": {
Expand Down Expand Up @@ -505,6 +514,10 @@
},
"rotation": 180
},
"CH->IT": {
"lonlat": [9.047334, 46.113596],
"rotation": 180
},
"CN->RU-AS": {
"lonlat": [123.275128, 53.541248],
"parsers": {
Expand Down Expand Up @@ -550,6 +563,10 @@
},
"rotation": 135
},
"DE->DK": {
"lonlat": [9.3, 54.9],
"rotation": 0
},
"DE->DK-DK1": {
"capacity": [-2500, 2500],
"lonlat": [9.3, 54.9],
Expand Down Expand Up @@ -601,6 +618,11 @@
},
"rotation": -10
},
"DE->NO": {
"capacity": [-1444, 1444],
"lonlat": [7.2, 55.9],
"rotation": -10
},
"DE->PL": {
"lonlat": [14.585163, 52.410625],
"parsers": {
Expand All @@ -618,6 +640,11 @@
},
"rotation": 0
},
"DE->SE": {
"lonlat": [13.552264, 54.925814],
"capacity": [-615, 615],
"rotation": 0
},
"DK-BHM->SE-SE4": {
"capacity": [-60, 60],
"lonlat": [14.509682, 55.363057],
Expand Down Expand Up @@ -663,6 +690,10 @@
},
"rotation": 70
},
"DK->SE": {
"lonlat": [11.556268, 56.857802],
"rotation": 70
},
"DK-DK2->SE-SE4": {
"capacity": [-1300, 1700],
"lonlat": [12.704418, 55.952282],
Expand Down Expand Up @@ -761,6 +792,10 @@
},
"rotation": -30
},
"FI->NO": {
"lonlat": [25.35158, 68.862684],
"rotation": -30
},
"FI->RU-1": {
"capacity": [-1460, 320],
"lonlat": [28.378, 60.878],
Expand All @@ -779,6 +814,10 @@
},
"rotation": -90
},
"FI->SE": {
"lonlat": [23.857, 66.921],
"rotation": -90
},
"FI->SE-SE3": {
"capacity": [-1200, 1200],
"lonlat": [19.797, 60.628],
Expand All @@ -805,6 +844,18 @@
},
"rotation": 70
},
"FR->IT": {
"lonlat": [6.9, 44.4],
"rotation": 70
},
"FR-COR->IT": {
"lonlat": [10.091148, 42.686804],
"parsers": {
"exchange": "ENTSOE.fetch_exchange",
"exchangeForecast": "ENTSOE.fetch_exchange_forecast"
},
"rotation": 45
},
"FR-COR->IT-CNO": {
"lonlat": [10.091148, 42.686804],
"parsers": {
Expand Down Expand Up @@ -865,6 +916,10 @@
},
"rotation": 50
},
"GB->NO": {
"lonlat": [2.44819, 57.266334],
"rotation": 50
},
"GE->RU-1": {
"lonlat": [42.822242, 43.158267],
"parsers": {
Expand Down Expand Up @@ -912,6 +967,10 @@
},
"rotation": -90
},
"GR->IT": {
"lonlat": [18.759248, 38.902132],
"rotation": -90
},
"GR->MK": {
"lonlat": [22.011736, 41.160374],
"parsers": {
Expand Down Expand Up @@ -1099,6 +1158,10 @@
},
"rotation": 90
},
"IT->SI": {
"lonlat": [13.596393, 46.105418],
"rotation": 90
},
"IT-SIC->IT-SO": {
"lonlat": [15.65, 38.1],
"parsers": {
Expand All @@ -1116,6 +1179,10 @@
},
"rotation": -160
},
"IT->MT": {
"lonlat": [14.675346, 36.264287],
"rotation": -160
},
"JP-CB->JP-HR": {
"lonlat": [136.85, 36.35],
"parsers": {
Expand Down Expand Up @@ -1234,6 +1301,10 @@
},
"rotation": -90
},
"LT->SE": {
"lonlat": [18.847674, 55.910978],
"rotation": -90
},
"LV->RU-1": {
"capacity": [-970, 970],
"lonlat": [27.7336, 56.87436],
Expand Down Expand Up @@ -1445,6 +1516,10 @@
},
"rotation": -90
},
"NO->SE": {
"lonlat": [14.055, 64.918],
"rotation": 100
},
"NO-NO1->SE-SE3": {
"capacity": [-2095, 2145],
"lonlat": [12.254138, 61.008235],
Expand Down Expand Up @@ -1516,6 +1591,10 @@
},
"rotation": 120
},
"NO->RU-1": {
"lonlat": [30.1437, 69.52],
"rotation": 120
},
"PL->SE-SE4": {
"capacity": [-600, 600],
"lonlat": [15.969256, 55.215172],
Expand All @@ -1525,6 +1604,11 @@
},
"rotation": -20
},
"PL->SE": {
"capacity": [-600, 600],
"lonlat": [15.969256, 55.215172],
"rotation": -20
},
"PL->SK": {
"lonlat": [20.614102, 49.359467],
"parsers": {
Expand Down Expand Up @@ -1587,16 +1671,16 @@
},
"SE-SE1->SE-SE2": {
"capacity": [-3300, 3300],
"lonlat": [17.869, 65.112],
"lonlat": [17.869, 65.469],
"parsers": {
"exchange": "ENTSOE.fetch_exchange",
"exchangeForecast": "ENTSOE.fetch_exchange_forecast"
},
"rotation": 180
"rotation": 205
},
"SE-SE2->SE-SE3": {
"capacity": [-7300, 7300],
"lonlat": [14.804, 61.661],
"lonlat": [14.804, 61.42],
"parsers": {
"exchange": "ENTSOE.fetch_exchange",
"exchangeForecast": "ENTSOE.fetch_exchange_forecast"
Expand All @@ -1605,7 +1689,7 @@
},
"SE-SE3->SE-SE4": {
"capacity": [-2000, 5400],
"lonlat": [14.518, 57.18],
"lonlat": [14.518, 57.78],
"parsers": {
"exchange": "ENTSOE.fetch_exchange",
"exchangeForecast": "ENTSOE.fetch_exchange_forecast"
Expand Down
2 changes: 1 addition & 1 deletion config/zones.json
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,7 @@
"production": "ENTSOE.fetch_production",
"productionPerModeForecast": "ENTSOE.fetch_wind_solar_forecasts"
},
"subZoneNames": ["DK-DK1", "DK-DK2"],
"subZoneNames": ["DK-DK1", "DK-DK2", "DK-BHM"],
"timezone": "Europe/Copenhagen"
},
"DK-BHM": {
Expand Down
14 changes: 14 additions & 0 deletions electricitymap/contrib/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@ def generate_zone_neighbours(
ZONES_CONFIG, EXCHANGES_CONFIG
)

# This object represents all neighbours regardless of granularity
def generate_all_neighbours(exchanges_config) -> Dict[ZoneKey, List[ZoneKey]]:
zone_neighbours = defaultdict(set)
for k, v in exchanges_config.items():
zone_1, zone_2 = k.split("->")
pairs = [(zone_1, zone_2), (zone_2, zone_1)]
for zone_name_1, zone_name_2 in pairs:
zone_neighbours[zone_name_1].add(zone_name_2)
# Sort
return {k: sorted(v) for k, v in zone_neighbours.items()}


ALL_NEIGHBOURS: Dict[ZoneKey, List[ZoneKey]] = generate_all_neighbours(EXCHANGES_CONFIG)


def emission_factors(zone_key: ZoneKey) -> Dict[str, float]:
override = CO2EQ_PARAMETERS["emissionFactors"]["zoneOverrides"].get(zone_key, {})
Expand Down
49 changes: 33 additions & 16 deletions web/geo/generate-exchanges-to-exclude.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,47 @@
const { getJSON, writeJSON, fileExists } = require('./utilities');
const exchangeConfig = require('../../config/exchanges.json');

const generateExchangesToIgnore = (OUT_PATH, fc) => {
const generateExchangesToIgnore = (OUT_PATH, zonesConfig) => {
console.log(`Generating new excluded-aggregated-exchanges.json...`); // eslint-disable-line no-console
const fcCombined = {
...fc,
features: fc.features.filter((feature) => {
try {
return feature.properties.isCombined;
} catch (e) {
console.log('Error: ', e, 'Feature: ', feature); // eslint-disable-line no-console
}
}),
};

const countryKeysToExclude = fcCombined.features.map((feature) => feature.properties.countryKey);
const countryKeysToExclude = Object.keys(zonesConfig).filter((key) => {
if (zonesConfig[key].subZoneNames?.length > 0) {
return key;
}
});

//Create a list of the exchange keys that we don't want to display in a country view
const unCombinedExchanges = Object.keys(exchangeConfig).filter((key) => {
const split = key.split('->');
const zoneOne = split[0].slice(0, 2);
const zoneTwo = split[1].slice(0, 2);
if (zoneOne === zoneTwo && countryKeysToExclude.includes(key.slice(0, 2))) {
const zoneOne = split[0];
const zoneTwo = split[1];

const subzoneSplitOne = zoneOne.split('-');
const subzoneSplitTwo = zoneTwo.split('-');
if (
(zoneOne.includes('-') && countryKeysToExclude.includes(subzoneSplitOne[0])) ||
(zoneTwo.includes('-') && countryKeysToExclude.includes(subzoneSplitTwo[0]))
) {
return key;
}
});
const exchanges = { exchangesToExclude: unCombinedExchanges };

//Create a list of the exchange keys that we don't want to display in the zone view
const countryExchangesWithSubzones = Object.keys(exchangeConfig).filter((key) => {
const split = key.split('->');
const zoneOne = split[0];
const zoneTwo = split[1];
if (
(!zoneOne.includes('-') && countryKeysToExclude.includes(zoneOne)) ||
(!zoneTwo.includes('-') && countryKeysToExclude.includes(zoneTwo))
) {
return key;
}
});
const exchanges = {
exchangesToExcludeCountryView: unCombinedExchanges,
exchangesToExcludeZoneView: countryExchangesWithSubzones,
};
const existingExchanges = fileExists(OUT_PATH) ? getJSON(OUT_PATH) : {};
if (JSON.stringify(exchanges) === JSON.stringify(existingExchanges)) {
console.log(`No changes to excluded-aggregated-exchanges.json`); // eslint-disable-line no-console
Expand Down
26 changes: 5 additions & 21 deletions web/geo/update-world.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
const path = require('path');

const { validateGeometry } = require('./validate');
const { validateGeometryV2 } = require('./validate-v2');
const { getJSON } = require('./utilities');
const { generateTopojson } = require('./generate-topojson');
const { generateAggregates } = require('./generate-aggregates');
const { generateExchangesToIgnore } = require('./generate-exchanges-to-exclude');
const { getZonesJson } = require('./files');

const config = {
WORLD_PATH: path.resolve(__dirname, './world.geojson'),
OUT_PATH: path.resolve(__dirname, '../src/world.json'),
ERROR_PATH: path.resolve(__dirname, '.'),
MIN_AREA_HOLES: 5000000,
MAX_CONVEX_DEVIATION: 0.708,
MIN_AREA_INTERSECTION: 500000,
SLIVER_RATIO: 0.0001, // ratio of length and area to determine if the polygon is a sliver and should be ignored
verifyNoUpdates: process.env.VERIFY_NO_UPDATES !== undefined,
};
const configV2 = {
WORLD_PATH: path.resolve(__dirname, './world.geojson'),
OUT_PATH: path.resolve(__dirname, '../src/world-aggregated.json'),
ERROR_PATH: path.resolve(__dirname, '.'),
Expand All @@ -32,15 +20,11 @@ const configV2 = {
const EXCHANGE_OUT_PATH = path.resolve(__dirname, '../src/excluded-aggregated-exchanges.json');

const fc = getJSON(config.WORLD_PATH);
validateGeometry(fc, config);
generateTopojson(fc, config);

const fcV2 = getJSON(config.WORLD_PATH);
const zoneConfig = getZonesJson();
const aggregates = generateAggregates(fcV2, zoneConfig);
const aggregates = generateAggregates(fc, zoneConfig);

fcV2.features = aggregates;
fc.features = aggregates;

validateGeometryV2(fcV2, configV2);
generateTopojson(fcV2, configV2);
generateExchangesToIgnore(EXCHANGE_OUT_PATH, fcV2);
validateGeometry(fc, config);
generateTopojson(fc, config);
generateExchangesToIgnore(EXCHANGE_OUT_PATH, zoneConfig);
Loading