Remove Lightning_Report_Automatic.json file, eliminating the associated n8n workflow and its components for report generation and token management. Update Lightning_Report_Manual.json to reflect changes in node positions and IDs, ensuring consistency across workflows. Enhance report generation logic by adding detailed strike list sections for cloud-to-ground and intercloud lightning events, improving clarity and user experience in report outputs.
This commit is contained in:
parent
7fd27ffed8
commit
8152e76d05
410
Import_Wind_Turbine_Farm.json
Normal file
410
Import_Wind_Turbine_Farm.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
4
examples/wind_turbines_sample.csv
Normal file
4
examples/wind_turbines_sample.csv
Normal file
@ -0,0 +1,4 @@
|
||||
name,latitude,longitude,farm_name
|
||||
WTG-01,39.854321,32.765432,Sample Wind Farm
|
||||
WTG-02,39.855100,32.766200,Sample Wind Farm
|
||||
WTG-03,39.855880,32.766968,Sample Wind Farm
|
||||
|
@ -31,6 +31,7 @@ _LIGHTNING_COLUMN_ALIASES: dict[str, list[str]] = {
|
||||
"time",
|
||||
"timestamp",
|
||||
],
|
||||
"ic_height": ["ic_height", "inCloudHeight", "in_cloud_height", "InCloudHeight"],
|
||||
}
|
||||
|
||||
_TURBINE_COLUMN_ALIASES: dict[str, list[str]] = {
|
||||
@ -158,6 +159,9 @@ def _build_lightning_df(
|
||||
if "current_abs" not in df.columns:
|
||||
df["current_abs"] = df["current"].abs()
|
||||
|
||||
if "ic_height" in df.columns:
|
||||
df["ic_height"] = pd.to_numeric(df["ic_height"], errors="coerce")
|
||||
|
||||
return df
|
||||
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import io
|
||||
import os
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import Any, Iterable
|
||||
from typing import Any, Iterable, Literal
|
||||
|
||||
import pandas as pd
|
||||
import matplotlib
|
||||
@ -163,6 +163,24 @@ def _add_paragraph(doc: Document, text: str, size_pt: int = 11, align: WD_ALIGN_
|
||||
r.font.size = Pt(size_pt)
|
||||
|
||||
|
||||
def _add_multiline_paragraph(
|
||||
doc: Document,
|
||||
text: str,
|
||||
size_pt: int = 11,
|
||||
align: WD_ALIGN_PARAGRAPH = WD_ALIGN_PARAGRAPH.LEFT,
|
||||
) -> None:
|
||||
lines = [line.strip() for line in text.splitlines() if line.strip()]
|
||||
if not lines:
|
||||
return
|
||||
p = doc.add_paragraph()
|
||||
p.alignment = align
|
||||
for index, line in enumerate(lines):
|
||||
if index > 0:
|
||||
p.add_run().add_break()
|
||||
run = p.add_run(line)
|
||||
run.font.size = Pt(size_pt)
|
||||
|
||||
|
||||
def _add_bullets(doc: Document, items: Iterable[str], size_pt: int = 10) -> None:
|
||||
for item in items:
|
||||
p = doc.add_paragraph(style="List Bullet")
|
||||
@ -499,6 +517,56 @@ def _fit_one_line_table_layout(
|
||||
return font_pt, [w * scale for w in required]
|
||||
|
||||
|
||||
def _add_detailed_strike_list_section(
|
||||
doc: Document,
|
||||
title: str,
|
||||
description: str,
|
||||
empty_message: str,
|
||||
centroid_lat: float,
|
||||
centroid_lng: float,
|
||||
lightning_df: pd.DataFrame,
|
||||
strike_type: Literal["cg", "ic"],
|
||||
content_width: float,
|
||||
lang,
|
||||
) -> None:
|
||||
_add_title(doc, title, size_pt=14)
|
||||
_add_multiline_paragraph(doc, description, size_pt=10)
|
||||
table_data, row_colors = build_lightning_event_table_data(
|
||||
centroid_lat,
|
||||
centroid_lng,
|
||||
lightning_df,
|
||||
lang,
|
||||
strike_type=strike_type,
|
||||
)
|
||||
if len(table_data) <= 1:
|
||||
_add_paragraph(doc, empty_message, size_pt=10)
|
||||
return
|
||||
|
||||
table_data[0] = [
|
||||
str(h).replace(" ", "\u00A0", 1) if " " in str(h) else str(h) for h in table_data[0]
|
||||
]
|
||||
available_width_cm = float(content_width) * 2.54
|
||||
if strike_type == "ic":
|
||||
min_col_widths_cm = [1, 3.2, 1.6, 1.6, 1.9, 1.4, 1.8]
|
||||
else:
|
||||
min_col_widths_cm = [1, 3.2, 1.6, 1.6, 1.9, 1.8]
|
||||
font_pt, col_widths_cm = _fit_one_line_table_layout(
|
||||
table_data=table_data,
|
||||
available_width_cm=available_width_cm,
|
||||
min_col_widths_cm=min_col_widths_cm,
|
||||
max_font_pt=15,
|
||||
min_font_pt=8,
|
||||
)
|
||||
_add_table(
|
||||
doc,
|
||||
table_data,
|
||||
row_colors=row_colors,
|
||||
column_widths_cm=col_widths_cm,
|
||||
font_size_pt=float(font_pt),
|
||||
autofit=False,
|
||||
)
|
||||
|
||||
|
||||
def _add_table(
|
||||
doc: Document,
|
||||
table_data: list[list[str]],
|
||||
@ -813,7 +881,7 @@ def create_docx_report(
|
||||
|
||||
doc.add_page_break()
|
||||
|
||||
# Farm-wide maps + charts + risk table, anchored at the n8n-supplied centroid.
|
||||
# Risk table, then farm-wide maps and charts anchored at the n8n-supplied centroid.
|
||||
centroid_row = pd.Series({
|
||||
"lat": centroid_lat,
|
||||
"lng": centroid_lng,
|
||||
@ -825,6 +893,13 @@ def create_docx_report(
|
||||
has_cg = bool(((type_values == "0") & mask_within).any())
|
||||
has_ic = bool(((type_values != "0") & mask_within).any())
|
||||
|
||||
risk_table_data, risk_row_colors = build_risk_table_data(turbine_df, lang)
|
||||
if risk_table_data and len(risk_table_data) > 1:
|
||||
_add_title(doc, s.turbine_risk_assessment, size_pt=14)
|
||||
_add_paragraph(doc, s.turbine_risk_assessment_desc, size_pt=10)
|
||||
_add_table(doc, risk_table_data, row_colors=risk_row_colors)
|
||||
doc.add_page_break()
|
||||
|
||||
if has_cg:
|
||||
_add_title(doc, s.cloud_to_ground_lightnings, size_pt=14)
|
||||
if start_date and end_date:
|
||||
@ -849,6 +924,18 @@ def create_docx_report(
|
||||
)
|
||||
if cg_chart is not None:
|
||||
_add_image_from_bytes(doc, cg_chart.to_image(format="png", width=1200, height=900, scale=2, engine="kaleido"), content_width)
|
||||
_add_detailed_strike_list_section(
|
||||
doc,
|
||||
s.detailed_cg_events,
|
||||
s.detailed_cg_events_desc,
|
||||
s.detailed_cg_events_empty,
|
||||
centroid_lat,
|
||||
centroid_lng,
|
||||
lightning_df,
|
||||
"cg",
|
||||
content_width,
|
||||
lang,
|
||||
)
|
||||
doc.add_page_break()
|
||||
|
||||
if has_ic:
|
||||
@ -875,13 +962,18 @@ def create_docx_report(
|
||||
)
|
||||
if ic_chart is not None:
|
||||
_add_image_from_bytes(doc, ic_chart.to_image(format="png", width=1200, height=900, scale=2, engine="kaleido"), content_width)
|
||||
doc.add_page_break()
|
||||
|
||||
risk_table_data, risk_row_colors = build_risk_table_data(turbine_df, lang)
|
||||
if risk_table_data and len(risk_table_data) > 1:
|
||||
_add_title(doc, s.turbine_risk_assessment, size_pt=14)
|
||||
_add_paragraph(doc, s.turbine_risk_assessment_desc, size_pt=10)
|
||||
_add_table(doc, risk_table_data, row_colors=risk_row_colors)
|
||||
_add_detailed_strike_list_section(
|
||||
doc,
|
||||
s.detailed_ic_events,
|
||||
s.detailed_ic_events_desc,
|
||||
s.detailed_ic_events_empty,
|
||||
centroid_lat,
|
||||
centroid_lng,
|
||||
lightning_df,
|
||||
"ic",
|
||||
content_width,
|
||||
lang,
|
||||
)
|
||||
doc.add_page_break()
|
||||
|
||||
# Daily breakdown
|
||||
@ -1081,30 +1173,6 @@ def create_docx_report(
|
||||
)
|
||||
doc.add_page_break()
|
||||
|
||||
# Farm-wide lightning event table, anchored at the n8n-supplied centroid.
|
||||
_add_title(doc, s.detailed_lightning_data, size_pt=14)
|
||||
table_data, row_colors = build_lightning_event_table_data(centroid_lat, centroid_lng, lightning_df, lang)
|
||||
if table_data and table_data[0]:
|
||||
table_data[0] = [str(h).replace(" ", "\u00A0", 1) if " " in str(h) else str(h) for h in table_data[0]]
|
||||
available_width_cm = float(content_width) * 2.54
|
||||
min_col_widths_cm = [1, 3.2, 1.6, 1.6, 1.9, 1.4, 2.0, 1.8]
|
||||
font_pt, col_widths_cm = _fit_one_line_table_layout(
|
||||
table_data=table_data,
|
||||
available_width_cm=available_width_cm,
|
||||
min_col_widths_cm=min_col_widths_cm,
|
||||
max_font_pt=15,
|
||||
min_font_pt=8,
|
||||
)
|
||||
_add_table(
|
||||
doc,
|
||||
table_data,
|
||||
row_colors=row_colors,
|
||||
column_widths_cm=col_widths_cm,
|
||||
font_size_pt=float(font_pt),
|
||||
autofit=False,
|
||||
)
|
||||
doc.add_page_break()
|
||||
|
||||
# Appendix
|
||||
_add_title(doc, s.appendix, size_pt=16)
|
||||
_add_title(doc, s.risk_calc_method, size_pt=14)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Callable
|
||||
from typing import Any, Callable, Literal
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
@ -280,17 +280,45 @@ def build_lightning_event_table_data(
|
||||
centroid_lng: float,
|
||||
lightning_df: pd.DataFrame,
|
||||
lang: ReportLanguage | None = None,
|
||||
strike_type: Literal["cg", "ic", "all"] = "all",
|
||||
) -> tuple[list[list[str]], list[str]]:
|
||||
s = get_strings(lang or get_report_language())
|
||||
include_type_column = strike_type == "all"
|
||||
include_height_column = strike_type != "cg"
|
||||
|
||||
if strike_type == "cg":
|
||||
source_df = lightning_df[lightning_df["p_type"].astype(str) == "0"].copy()
|
||||
elif strike_type == "ic":
|
||||
source_df = lightning_df[lightning_df["p_type"].astype(str) != "0"].copy()
|
||||
else:
|
||||
source_df = lightning_df.copy()
|
||||
|
||||
header = [
|
||||
s.col_no,
|
||||
s.col_time_local,
|
||||
s.col_lat,
|
||||
s.col_lng,
|
||||
s.col_current_amps,
|
||||
]
|
||||
if include_height_column:
|
||||
header.append(s.col_height_m)
|
||||
if include_type_column:
|
||||
header.append(s.col_lightning_type)
|
||||
header.append(s.col_proximity_km)
|
||||
|
||||
if source_df.empty:
|
||||
return [header], ["lightgrey"]
|
||||
|
||||
pre = precompute_distances_and_rings(
|
||||
centroid_lat, centroid_lng, lightning_df, config.distance_rings
|
||||
centroid_lat, centroid_lng, source_df, config.distance_rings
|
||||
)
|
||||
rows: list[list[str]] = []
|
||||
row_colors: list[str] = []
|
||||
outermost_km = max(config.distance_rings) / 1000.0
|
||||
rings_km = [r / 1000.0 for r in config.distance_rings]
|
||||
proximity_index = len(header) - 1
|
||||
|
||||
for i, rec in enumerate(lightning_df.itertuples(index=False)):
|
||||
for i, rec in enumerate(source_df.itertuples(index=False)):
|
||||
proximity = float(pre["dists_km"][i])
|
||||
if proximity > outermost_km:
|
||||
continue
|
||||
@ -310,48 +338,43 @@ def build_lightning_event_table_data(
|
||||
except Exception:
|
||||
local_time = str(getattr(rec, "local_time", ""))[:19]
|
||||
|
||||
lightning_type = s.lightning_type_cg if str(rec.p_type) == "0" else s.lightning_type_ic
|
||||
height_val = getattr(rec, "ic_height", "")
|
||||
if height_val == "":
|
||||
height_val = getattr(rec, "height", "")
|
||||
|
||||
rows.append(
|
||||
[
|
||||
row = [
|
||||
"",
|
||||
local_time,
|
||||
f"{rec.lat:.5f}",
|
||||
f"{rec.lng:.5f}",
|
||||
str(rec.current),
|
||||
str(height_val),
|
||||
lightning_type,
|
||||
f"{proximity:.2f}",
|
||||
]
|
||||
)
|
||||
if include_height_column:
|
||||
height_val = getattr(rec, "ic_height", "")
|
||||
if height_val == "" or pd.isna(height_val):
|
||||
height_val = getattr(rec, "inCloudHeight", "")
|
||||
row.append("" if height_val == "" or pd.isna(height_val) else str(height_val))
|
||||
if include_type_column:
|
||||
lightning_type = s.lightning_type_cg if str(rec.p_type) == "0" else s.lightning_type_ic
|
||||
row.append(lightning_type)
|
||||
row.append(f"{proximity:.2f}")
|
||||
rows.append(row)
|
||||
row_colors.append(color)
|
||||
|
||||
if rows:
|
||||
if include_type_column:
|
||||
type_index = proximity_index - 1
|
||||
sorted_data = sorted(
|
||||
zip(rows, row_colors),
|
||||
key=lambda x: (0 if x[0][6] == s.lightning_type_cg else 1, float(x[0][7])),
|
||||
key=lambda x: (0 if x[0][type_index] == s.lightning_type_cg else 1, float(x[0][proximity_index])),
|
||||
)
|
||||
else:
|
||||
sorted_data = sorted(
|
||||
zip(rows, row_colors),
|
||||
key=lambda x: float(x[0][proximity_index]),
|
||||
)
|
||||
if sorted_data:
|
||||
rows, row_colors = zip(*sorted_data)
|
||||
rows = list(rows)
|
||||
row_colors = list(row_colors)
|
||||
for idx, row in enumerate(rows):
|
||||
row[0] = str(idx + 1)
|
||||
else:
|
||||
rows, row_colors = [], []
|
||||
|
||||
header = [
|
||||
s.col_no,
|
||||
s.col_time_local,
|
||||
s.col_lat,
|
||||
s.col_lng,
|
||||
s.col_current_amps,
|
||||
s.col_height_m,
|
||||
s.col_lightning_type,
|
||||
s.col_proximity_km,
|
||||
]
|
||||
return [header] + rows, ["lightgrey"] + row_colors
|
||||
|
||||
|
||||
|
||||
@ -98,6 +98,12 @@ class ReportStrings:
|
||||
storm_cells: str
|
||||
storm_cells_daily_viz: str
|
||||
detailed_lightning_data: str
|
||||
detailed_cg_events: str
|
||||
detailed_ic_events: str
|
||||
detailed_cg_events_desc: str
|
||||
detailed_ic_events_desc: str
|
||||
detailed_cg_events_empty: str
|
||||
detailed_ic_events_empty: str
|
||||
appendix: str
|
||||
risk_calc_method: str
|
||||
how_risk_determined: str
|
||||
@ -308,6 +314,19 @@ _STRINGS_EN = ReportStrings(
|
||||
storm_cells="Storm Cells",
|
||||
storm_cells_daily_viz="Daily storm cells visualization.",
|
||||
detailed_lightning_data="Detailed Lightning Event Data",
|
||||
detailed_cg_events="Detailed Cloud-to-Ground Lightning List",
|
||||
detailed_ic_events="Detailed Intercloud Lightning List",
|
||||
detailed_cg_events_desc=(
|
||||
"Current (amps): peak current of the cloud-to-ground strike.\n"
|
||||
"Proximity (km): air distance from the strike to the wind farm centroid."
|
||||
),
|
||||
detailed_ic_events_desc=(
|
||||
"Current (amps): peak current of the in-cloud strike.\n"
|
||||
"Height (m): in-cloud flash height.\n"
|
||||
"Proximity (km): air distance from the strike to the wind farm centroid."
|
||||
),
|
||||
detailed_cg_events_empty="No cloud-to-ground lightning events were recorded within the analysis area during this period.",
|
||||
detailed_ic_events_empty="No intercloud lightning events were recorded within the analysis area during this period.",
|
||||
appendix="Appendix",
|
||||
risk_calc_method="1. Risk Calculation Method",
|
||||
how_risk_determined="How Risk Scores Are Determined:",
|
||||
@ -328,14 +347,14 @@ _STRINGS_EN = ReportStrings(
|
||||
max_risk_score="Maximum Risk Score: ~2.500 (close distance, high current)",
|
||||
typical_range="Typical Range: 0.010 - 1.000 for most lightning events",
|
||||
risk_categories="Risk Score Categories (Fixed Color Intervals):",
|
||||
risk_cat_very_low="Very Low Risk (<0.1): Blue - Distant lightning with low current",
|
||||
risk_cat_low="Low Risk (0.1-0.2): Teal - Moderate distance lightning",
|
||||
risk_cat_med_low="Med-Low Risk (0.2-0.4): Green - Closer lightning",
|
||||
risk_cat_medium="Medium Risk (0.4-0.6): Yellow - Moderate risk lightning",
|
||||
risk_cat_med_high="Med-High Risk (0.6-0.8): Orange - High risk lightning",
|
||||
risk_cat_high="High Risk (0.8-1.0): Dark Orange - Very high risk lightning",
|
||||
risk_cat_very_high="Very High Risk (1.0-1.2): Red - Extreme risk lightning",
|
||||
risk_cat_critical="Critical Risk (>1.2): Dark Red - Critical risk lightning",
|
||||
risk_cat_very_low="Very Low Risk (<0.1): Blue",
|
||||
risk_cat_low="Low Risk (0.1-0.2): Teal",
|
||||
risk_cat_med_low="Med-Low Risk (0.2-0.4): Green",
|
||||
risk_cat_medium="Medium Risk (0.4-0.6): Yellow",
|
||||
risk_cat_med_high="Med-High Risk (0.6-0.8): Orange",
|
||||
risk_cat_high="High Risk (0.8-1.0): Dark Orange",
|
||||
risk_cat_very_high="Very High Risk (1.0-1.2): Red",
|
||||
risk_cat_critical="Critical Risk (>1.2): Dark Red",
|
||||
risk_chart="3. Risk Score Calculation Chart",
|
||||
chart_reference="Chart Reference Guide:",
|
||||
risk_chart_desc_1="The following chart shows how distance and current magnitude affect risk scores.",
|
||||
@ -527,6 +546,19 @@ _STRINGS_TR = ReportStrings(
|
||||
storm_cells="Fırtına Hücreleri",
|
||||
storm_cells_daily_viz="Fırtına hücrelerinin dağılımı",
|
||||
detailed_lightning_data="Ayrıntılı Yıldırım Olay Verileri",
|
||||
detailed_cg_events="Ayrıntılı Yıldırım Listesi",
|
||||
detailed_ic_events="Ayrıntılı Şimşek Listesi",
|
||||
detailed_cg_events_desc=(
|
||||
"Akım (amper): yıldırımın akım büyüklüğü.\n"
|
||||
"Yakınlık (km): yıldırımın rüzgar çiftliğinin merkez noktasına (centroid) olan kuş uçuşu mesafesi."
|
||||
),
|
||||
detailed_ic_events_desc=(
|
||||
"Akım (amper): şimşeğin akım büyüklüğü.\n"
|
||||
"Yükseklik (m): şimşeğin oluştuğu yükseklik.\n"
|
||||
"Yakınlık (km): şimşeğin rüzgar çiftliğinin merkez noktasına olan kuş uçuşu mesafesi."
|
||||
),
|
||||
detailed_cg_events_empty="Bu dönemde analiz alanında yıldırım olayı kaydedilmemiştir.",
|
||||
detailed_ic_events_empty="Bu dönemde analiz alanında şimşek olayı kaydedilmemiştir.",
|
||||
appendix="Ek",
|
||||
risk_calc_method="1. Risk Hesaplama Yöntemi",
|
||||
how_risk_determined="Risk Skorları Nasıl Belirlenir:",
|
||||
@ -547,14 +579,14 @@ _STRINGS_TR = ReportStrings(
|
||||
max_risk_score="Maksimum Risk Skoru: ~2.500 (yakın mesafe, yüksek akım)",
|
||||
typical_range="Tipik Aralık: çoğu yıldırım olayı için 0.010 - 1.000",
|
||||
risk_categories="Risk Skoru Kategorileri (Sabit Renk Aralıkları):",
|
||||
risk_cat_very_low="Çok Düşük Risk (<0.1): Mavi - Uzak, düşük akımlı yıldırım",
|
||||
risk_cat_low="Düşük Risk (0.1-0.2): Turkuaz - Orta mesafeli yıldırım",
|
||||
risk_cat_med_low="Orta-Düşük Risk (0.2-0.4): Yeşil - Daha yakın yıldırım",
|
||||
risk_cat_medium="Orta Risk (0.4-0.6): Sarı - Orta riskli yıldırım",
|
||||
risk_cat_med_high="Orta-Yüksek Risk (0.6-0.8): Turuncu - Yüksek riskli yıldırım",
|
||||
risk_cat_high="Yüksek Risk (0.8-1.0): Koyu Turuncu - Çok yüksek riskli yıldırım",
|
||||
risk_cat_very_high="Çok Yüksek Risk (1.0-1.2): Kırmızı - Aşırı riskli yıldırım",
|
||||
risk_cat_critical="Kritik Risk (>1.2): Koyu Kırmızı - Kritik riskli yıldırım",
|
||||
risk_cat_very_low="Çok düşük risk (<0.1): Mavi",
|
||||
risk_cat_low="Düşük Risk (0.1-0.2): Turkuaz",
|
||||
risk_cat_med_low="Orta-Düşük Risk (0.2-0.4): Yeşil",
|
||||
risk_cat_medium="Orta Risk (0.4-0.6): Sarı",
|
||||
risk_cat_med_high="Orta-Yüksek Risk (0.6-0.8): Turuncu",
|
||||
risk_cat_high="Yüksek Risk (0.8-1.0): Koyu Turuncu",
|
||||
risk_cat_very_high="Çok Yüksek Risk (1.0-1.2): Kırmızı",
|
||||
risk_cat_critical="Kritik Risk (>1.2): Koyu Kırmızı",
|
||||
risk_chart="3. Risk Skoru Hesaplama Grafiği",
|
||||
chart_reference="Grafik Referans Kılavuzu:",
|
||||
risk_chart_desc_1="Aşağıdaki grafik, mesafe ve akım büyüklüğünün risk skorlarını nasıl etkilediğini gösterir.",
|
||||
|
||||
@ -11,6 +11,8 @@ COORDINATE_PLANE_RING_LINE_WIDTH = 4
|
||||
COORDINATE_PLANE_LIGHTNING_SIZE_MIN = 10
|
||||
COORDINATE_PLANE_LIGHTNING_SIZE_MAX = 24
|
||||
COORDINATE_PLANE_LIGHTNING_CURRENT_SCALE = 800
|
||||
COORDINATE_PLANE_TURBINE_NAME_FONT_SIZE = 9
|
||||
COORDINATE_PLANE_TURBINE_TEXT_POSITION = 'middle center'
|
||||
|
||||
def plot_turbine_map(turbine_row: pd.Series, lightning_df: pd.DataFrame, turbine_df: pd.DataFrame) -> go.Figure:
|
||||
turbine_lat = turbine_row['lat']
|
||||
@ -371,8 +373,8 @@ def plot_coordinate_plane(turbine_row: pd.Series, lightning_df: pd.DataFrame, tu
|
||||
line=dict(color='black', width=1)
|
||||
),
|
||||
text=turbine_df['name'].tolist(),
|
||||
textfont=dict(size=18, color='black'), # turbine name label font size
|
||||
textposition='middle center',
|
||||
textfont=dict(size=COORDINATE_PLANE_TURBINE_NAME_FONT_SIZE, color='black'),
|
||||
textposition=COORDINATE_PLANE_TURBINE_TEXT_POSITION,
|
||||
name='Wind Turbines',
|
||||
showlegend=True
|
||||
))
|
||||
@ -394,7 +396,7 @@ def plot_coordinate_plane(turbine_row: pd.Series, lightning_df: pd.DataFrame, tu
|
||||
line=dict(color='black', width=1)
|
||||
),
|
||||
text=['S'] * len(storm_df),
|
||||
textfont=dict(size=18, color='white'), # storm "S" label font size
|
||||
textfont=dict(size=18, color='white'),
|
||||
textposition='middle center',
|
||||
name='Storm Cells',
|
||||
showlegend=True
|
||||
@ -521,8 +523,8 @@ def plot_intercloud_coordinate_plane(turbine_row: pd.Series, lightning_df: pd.Da
|
||||
line=dict(color='black', width=1)
|
||||
),
|
||||
text=turbine_df['name'].tolist(),
|
||||
textfont=dict(size=24, color='black'),
|
||||
textposition='middle center',
|
||||
textfont=dict(size=COORDINATE_PLANE_TURBINE_NAME_FONT_SIZE, color='black'),
|
||||
textposition=COORDINATE_PLANE_TURBINE_TEXT_POSITION,
|
||||
name=s.map_wind_turbines,
|
||||
showlegend=True
|
||||
))
|
||||
@ -694,8 +696,8 @@ def plot_cloud_to_ground_coordinate_plane(turbine_row: pd.Series, lightning_df:
|
||||
line=dict(color='black', width=1)
|
||||
),
|
||||
text=turbine_df['name'].tolist(),
|
||||
textfont=dict(size=18, color='black'), # turbine name label font size
|
||||
textposition='middle center',
|
||||
textfont=dict(size=COORDINATE_PLANE_TURBINE_NAME_FONT_SIZE, color='black'),
|
||||
textposition=COORDINATE_PLANE_TURBINE_TEXT_POSITION,
|
||||
name=s.map_wind_turbines,
|
||||
showlegend=True
|
||||
))
|
||||
@ -717,7 +719,7 @@ def plot_cloud_to_ground_coordinate_plane(turbine_row: pd.Series, lightning_df:
|
||||
line=dict(color='black', width=1)
|
||||
),
|
||||
text=['S'] * len(storm_df),
|
||||
textfont=dict(size=18, color='white'), # storm "S" label font size
|
||||
textfont=dict(size=18, color='white'),
|
||||
textposition='middle center',
|
||||
name=s.map_storm_cells,
|
||||
showlegend=True
|
||||
|
||||
@ -13,6 +13,10 @@ from src.config import config
|
||||
from src.reporting.strings import ReportLanguage, get_report_language, get_strings
|
||||
from src.utils import parse_period_string_to_datetime
|
||||
from src.visualization.basemap import add_satellite_basemap
|
||||
from src.visualization.maps import (
|
||||
COORDINATE_PLANE_TURBINE_NAME_FONT_SIZE,
|
||||
COORDINATE_PLANE_TURBINE_TEXT_POSITION,
|
||||
)
|
||||
|
||||
def format_datetime_for_display(datetime_str: str) -> str:
|
||||
"""
|
||||
@ -177,8 +181,8 @@ def create_storm_cells_coordinate_plane(storm_data: List[Dict], turbine_df: pd.D
|
||||
line=dict(color='black', width=1)
|
||||
),
|
||||
text=turbine_df['name'].tolist(),
|
||||
textfont=dict(size=12, color='black'),
|
||||
textposition='middle center',
|
||||
textfont=dict(size=COORDINATE_PLANE_TURBINE_NAME_FONT_SIZE, color='black'),
|
||||
textposition=COORDINATE_PLANE_TURBINE_TEXT_POSITION,
|
||||
name=s.map_wind_turbines,
|
||||
showlegend=True,
|
||||
hovertemplate=(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user