diff --git a/DMI_Open_Data_dialog.py b/DMI_Open_Data_dialog.py index 82e6338..5b5d055 100644 --- a/DMI_Open_Data_dialog.py +++ b/DMI_Open_Data_dialog.py @@ -1,37 +1,34 @@ # -*- coding: utf-8 -*- import os -from typing import Tuple, Dict, Set +from typing import Tuple, Dict, Set, List from qgis.PyQt import QtWidgets, uic import requests import pandas as pd -from pandas.io.json import json_normalize +from pandas import json_normalize import warnings from tempfile import mkdtemp from qgis.core import QgsVectorLayer, QgsProcessing, QgsProcessingFeedback, QgsRasterLayer, QgsContrastEnhancement, QgsRasterMinMaxOrigin, QgsFeature, QgsGeometry, QgsField, QgsPointXY, QgsProject, QgsRasterLayerTemporalProperties, QgsDateTimeRange, QgsColorRampShader, QgsRasterShader, QgsSingleBandPseudoColorRenderer, QgsSingleBandGrayRenderer, QgsRasterBandStats -from qgis.PyQt.QtGui import ( - QColor) from qgis.utils import iface from PyQt5.QtCore import * from PyQt5.QtWidgets import * from qgis.PyQt.QtCore import QVariant import webbrowser -from .forecast_para import depth_para_dkss, salinity_nsbs, salinity_idw, salinity_if, salinity_lb, salinity_lf, salinity_ws, water_temp_nsbs, water_temp_if, water_temp_lb, water_temp_lf, water_temp_ws, water_temp_idw, v_current_nsbs, v_current_idw, v_current_if, v_current_lb, v_current_lf, v_current_ws, u_current_nsbs, u_current_idw, u_current_if,u_current_lb, u_current_lf, u_current_ws -import processing + +from .api.edr_parameters import get_forecast_parameters, EDRForecastCollection from .api.station import get_stations, StationApi, StationId, Station, Parameter from .settings import DMISettingsManager, DMISettingKeys warnings.simplefilter(action='ignore', category=FutureWarning) # The lists that will be used for parameters, stations, municipalities, 10 and 20km grids in the API calls. # Stations are not part of this list, as stations are more dynamicly added and removed. -# Stations are therefore imported from DMI Open Data via. the internet, each time QGIS is started. -from .para_munic_grid import para_grid, grid10, grid20, munic +# Stations are therefore imported from DMI Open Data via. API call, each time QGIS is started. +from .para_munic_grid import para_grid, grid10, grid20, munic_id_name +from .forecast_para import depth_para_dkss, salinity_nsbs, salinity_idw, salinity_if, salinity_lb, salinity_lf, salinity_ws, water_temp_nsbs, water_temp_if, water_temp_lb, water_temp_lf, water_temp_ws, water_temp_idw, v_current_nsbs, v_current_idw, v_current_if, v_current_lb, v_current_lf, v_current_ws, u_current_nsbs, u_current_idw, u_current_if,u_current_lb, u_current_lf, u_current_ws # This loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer # Ignore this, we no longer use the static ui files, look at pluginui_test.py instead FORM_CLASS, _ = uic.loadUiType(os.path.join( os.path.dirname(__file__), 'DMI_Open_Data_dialog_base.ui')) -########### DELETE ############## - # This is where you import and inherit your PY UI class class DMIOpenDataDialog(QtWidgets.QDialog, FORM_CLASS): @@ -71,6 +68,29 @@ def __init__(self, settings_manager: DMISettingsManager, parent=None): self.tr(str(ex))) load_ui_options['invalid_metobs_api_key'] = True + self.harmonie_nea_sf_forecast_parameters = self.get_forecast_parameters_if_settings_allow( + EDRForecastCollection.HARMONIE_NEA_SF) + self.harmonie_nea_pl_forecast_parameters = self.get_forecast_parameters_if_settings_allow( + EDRForecastCollection.HARMONIE_NEA_PL) + self.harmonie_igb_sf_forecast_parameters = self.get_forecast_parameters_if_settings_allow( + EDRForecastCollection.HARMONIE_IGB_SF) + self.harmonie_igb_pl_forecast_parameters = self.get_forecast_parameters_if_settings_allow( + EDRForecastCollection.HARMONIE_IGB_PL) + self.dkss_nsbs_forecast_parameters = self.get_forecast_parameters_if_settings_allow( + EDRForecastCollection.DKSS_NSBS) + self.dkss_idw_forecast_parameters = self.get_forecast_parameters_if_settings_allow( + EDRForecastCollection.DKSS_IDW) + self.dkss_if_forecast_parameters = self.get_forecast_parameters_if_settings_allow( + EDRForecastCollection.DKSS_IF) + self.dkss_ws_forecast_parameters = self.get_forecast_parameters_if_settings_allow( + EDRForecastCollection.DKSS_WS) + self.dkss_lf_forecast_parameters = self.get_forecast_parameters_if_settings_allow( + EDRForecastCollection.DKSS_LF) + self.dkss_lb_forecast_parameters = self.get_forecast_parameters_if_settings_allow( + EDRForecastCollection.DKSS_LB) + self.wam_forecast_parameters = self.get_forecast_parameters_if_settings_allow( + EDRForecastCollection.WAM_DW) + super(DMIOpenDataDialog, self).setupUi(self) self.load_station_and_parameter_ui(**load_ui_options) @@ -85,16 +105,19 @@ def __init__(self, settings_manager: DMISettingsManager, parent=None): self.radioButton_19.setChecked(True) self.radioButton_21.setChecked(True) self.wam_fore.setChecked(True) + self.wam_fore_grib.setChecked(True) self.north_sea_baltic_sea.setChecked(True) + self.north_sea_baltic_sea_2.setChecked(True) self.danish_waters.setChecked(True) - #self.all_para_dkss.setChecked(True) - #self.all_para_wam.setChecked(True) - self.dev_sea_mean.setChecked(True) - self.wind_speed_10.setChecked(True) self.composite.setChecked(True) self.full_range.setChecked(True) self._60960.setChecked(True) self.all_lightning_types.setChecked(True) + self.harm_fore.setChecked(True) + self.nea_sf_area.setChecked(True) + self.dev_sea_mean.setChecked(True) + self.wind_speed_10.setChecked(True) + self.danish_waters_2.setChecked(True) # Datetime default today and yesterday @@ -113,6 +136,9 @@ def __init__(self, settings_manager: DMISettingsManager, parent=None): self.datetime_fore_start.setDateTime(QDateTime(QDate.currentDate().addDays(1), QTime(22, 00, 0))) self.datetime_fore_end.setDateTime(QDateTime(QDate.currentDate().addDays(2), QTime(0, 0, 0))) + self.datetime_fore_start_2.setDateTime(QDateTime(QDate.currentDate().addDays(1), QTime(22, 00, 0))) + self.datetime_fore_end_2.setDateTime(QDateTime(QDate.currentDate().addDays(2), QTime(0, 0, 0))) + self.start_date5.setDateTime(QDateTime(QDate.currentDate().addDays(-1), QTime(0, 0, 0))) self.end_date5.setDateTime(QDateTime(QDate.currentDate(), QTime(0, 0, 0))) @@ -124,52 +150,100 @@ def __init__(self, settings_manager: DMISettingsManager, parent=None): # All the buttons that do actions self.run_app.clicked.connect(self.run) + + #Browse folder when saving as .csv self.browse_obs.clicked.connect(self.browse_files_obs) self.browse_cli.clicked.connect(self.browse_files_cli) self.browse_lig.clicked.connect(self.browse_files_lig) self.browse_oce.clicked.connect(self.browse_files_oce) + self.browse_fore.clicked.connect(self.browse_files_fore) + + # Change parameter and station view when clicked in Climate Data. self.stat_type.clicked.connect(self.stat_typeR) self.grid10_type.clicked.connect(self.grid10_typeR) self.grid20_type.clicked.connect(self.grid20_typeR) self.munic_type.clicked.connect(self.municipality_typeR) self.country_type.clicked.connect(self.country_typeR) + + # Opens dmi.dk self.dmi_open_data.clicked.connect(self.open_openData) self.dmi_open_data_2.clicked.connect(self.open_openData_2) self.dmi_dk.clicked.connect(self.open_dmi_dk) + + # Sets the initial page displayed self.stackedWidget.setCurrentWidget(self.stat_clima) self.stackedWidget_2.setCurrentWidget(self.stat_para) self.stackedWidget_3.setCurrentWidget(self.met_stat_page) + self.harm_para_stacked.setCurrentWidget(self.harm_nea_sf_para) + self.para_stacked.setCurrentWidget(self.harmonie_page) + self.para_stacked_2.setCurrentWidget(self.wam_page_2) + self.stacked_depth.setCurrentWidget(self.nsbs_depth) + self.depth_group.setEnabled(False) + + # Changes the page in Stations and Parameters self.met_stat_info.clicked.connect(self.infoStat) - self.para_stacked.setCurrentWidget(self.wam_page) - self.stackedWidget_4.setCurrentWidget(self.nsbs_depth) - self.wam_fore.clicked.connect(self.wamTab) - self.dkss_fore.clicked.connect(self.dkssTab) self.tide_info.clicked.connect(self.infoTide) + + # Defines time availability in Stations and Parameters self.radioButton_10.clicked.connect(self.disable_time) self.radioButton_11.clicked.connect(self.enable_time) self.radioButton_21.clicked.connect(self.disable_time_oce) self.radioButton_22.clicked.connect(self.enable_time_oce) - self.north_sea_baltic_sea.clicked.connect(self.nsbs_depth_tab) - self.inner_danish_waters.clicked.connect(self.idw_depth_tab) - self.wadden_sea.clicked.connect(self.ws_depth_tab) - self.isefjord.clicked.connect(self.if_depth_tab) - self.limfjord.clicked.connect(self.lf_depth_tab) - self.little_belt.clicked.connect(self.lb_depth_tab) + + # Changes the page in Forecast Data + self.wam_fore.clicked.connect(self.wamTab) + self.dkss_fore.clicked.connect(self.dkssTab) + self.harm_fore.clicked.connect(self.harmonieTab) + + #EDR + self.inner_danish_waters.clicked.connect(self.idw_tab) + self.north_sea_baltic_sea.clicked.connect(self.nsbs_tab) + self.limfjord.clicked.connect(self.lf_tab) + self.little_belt.clicked.connect(self.lb_tab) + self.wadden_sea.clicked.connect(self.ws_tab) + self.isefjord.clicked.connect(self.if_tab) + + + #GRIB + self.north_sea_baltic_sea_2.clicked.connect(self.nsbs_depth_tab) + self.inner_danish_waters_2.clicked.connect(self.idw_depth_tab) + self.wadden_sea_2.clicked.connect(self.ws_depth_tab) + self.isefjord_2.clicked.connect(self.if_depth_tab) + self.limfjord_2.clicked.connect(self.lf_depth_tab) + self.little_belt_2.clicked.connect(self.lb_depth_tab) self.dev_sea_mean.clicked.connect(self.depth_tab_dis) self.u_comp_wind.clicked.connect(self.depth_tab_dis) self.v_comp_wind.clicked.connect(self.depth_tab_dis) self.u_comp_cur.clicked.connect(self.depth_tab_dis) self.v_comp_cur.clicked.connect(self.depth_tab_dis) self.water_temp.clicked.connect(self.depth_tab_dis) - self.salinity.clicked.connect(self.depth_tab_dis) + self.salinity_2.clicked.connect(self.depth_tab_dis) self.ice_thick.clicked.connect(self.depth_tab_dis) self.ice_conc.clicked.connect(self.depth_tab_dis) self.u_comp_cur_.clicked.connect(self.depth_tab_enabled) self.v_comp_cur_.clicked.connect(self.depth_tab_enabled) self.water_temp_.clicked.connect(self.depth_tab_enabled) self.salinity_.clicked.connect(self.depth_tab_enabled) + + self.wam_fore_grib.clicked.connect(self.wamTab_grib) + self.dkss_fore_grib.clicked.connect(self.dkssTab_grib) + + # Sets the correct parameter page for Forecast + self.nea_sf_area.clicked.connect(self.neaSfTab) + self.nea_pl_area.clicked.connect(self.neaPlTab) + self.igb_sf_area.clicked.connect(self.igbSfTab) + self.igb_pl_area.clicked.connect(self.igbPlTab) + + # Defines coordinates or BBOX availability in forecast + self.coordi_harm.clicked.connect(self.enableCoordi) + self.bbox_harm.clicked.connect(self.enableBBox) + self.coordi_line.setEnabled(False) + self.bbox_harm.setChecked(True) + + # Changes the page for radar type self.composite.clicked.connect(self.comp) self.pseudo.clicked.connect(self.pseud) + self.stat_radar.setEnabled(False) # Sets the time in "Stations and parameters" unavailable untill "Defined Time" has been checked self.groupBox_25.setEnabled(False) @@ -177,16 +251,13 @@ def __init__(self, settings_manager: DMISettingsManager, parent=None): self.dateTimeEdit_3.setEnabled(False) self.dateTimeEdit_4.setEnabled(False) - self.groupBox_14.setEnabled(False) - - self.stat_radar.setEnabled(False) - + # Defines the objects used if API key not defined. self.radar_disable_if_needed() self.lightning_disable_if_needed() self.metobs_disable_if_needed() self.climate_disable_if_needed() self.ocean_disable_if_needed() - self.forecast_disable_if_needed() + self.forecast_GRIB_disable_if_needed() self.stat_info_disable_if_needed() # Disables data-tab if no API key has been entered @@ -197,11 +268,18 @@ def stat_info_disable_if_needed(self): layout.addWidget(DMIOpenDataDialog.generate_no_api_key_label(DMISettingKeys.METOBS_API_KEY)) self.tab_8.setEnabled(False) - def forecast_disable_if_needed(self): - api_key = self.settings_manager.value(DMISettingKeys.FORECASTDATA_API_KEY.value) + def forecast_GRIB_disable_if_needed(self): + api_key = self.settings_manager.value(DMISettingKeys.FORECASTDATA_GRIB_API_KEY.value) + if api_key == '': + layout = self.tab_7.findChildren(QtWidgets.QVBoxLayout)[0] + layout.addWidget(DMIOpenDataDialog.generate_no_api_key_label(DMISettingKeys.FORECASTDATA_GRIB_API_KEY)) + self.tab_7.setEnabled(False) + + def forecast_EDR_disable_if_needed(self): + api_key = self.settings_manager.value(DMISettingKeys.FORECASTDATA_EDR_API_KEY.value) if api_key == '': layout = self.tab_4.findChildren(QtWidgets.QVBoxLayout)[0] - layout.addWidget(DMIOpenDataDialog.generate_no_api_key_label(DMISettingKeys.FORECASTDATA_API_KEY)) + layout.addWidget(DMIOpenDataDialog.generate_no_api_key_label(DMISettingKeys.FORECASTDATA_EDR_API_KEY)) self.tab_4.setEnabled(False) def ocean_disable_if_needed(self): @@ -248,6 +326,13 @@ def get_stations_and_parameters_if_settings_allow(self, station_type: StationApi parameters = {parameter for station in stations.values() for parameter in station.parameters } return stations, parameters + def get_forecast_parameters_if_settings_allow(self, forecast_collection: EDRForecastCollection) -> List[str]: # TODO return Parameter + api_key = self.settings_manager.value(DMISettingKeys.FORECASTDATA_EDR_API_KEY.value) + parameters = [] + if api_key: + parameters = [p[0] for p in get_forecast_parameters(forecast_collection, api_key)] + return parameters + def load_station_and_parameter_ui(self, invalid_metobs_api_key=False, invalid_oceanobs_api_key=False, invalid_climate_api_key=False): # Creates the checkboxes for parameters in metObs self.listCheckBox_para_stat_metObs = \ @@ -272,13 +357,47 @@ def load_station_and_parameter_ui(self, invalid_metobs_api_key=False, invalid_oc self.display_parameters(grid20, DMISettingKeys.CLIMATEDATA_API_KEY, self.scrollAreaWidgetContents_4, invalid_api_key=invalid_climate_api_key) # Creates the checkboxes for municipalities in climateData self.listCheckBox_municipalityId = \ - self.display_parameters(munic, DMISettingKeys.CLIMATEDATA_API_KEY, self.scrollAreaWidgetContents_7, invalid_api_key=invalid_climate_api_key) + self.display_parameters(munic_id_name, DMISettingKeys.CLIMATEDATA_API_KEY, self.scrollAreaWidgetContents_7, invalid_api_key=invalid_climate_api_key) # Creates the checkboxes for stations in oceanObs self.listCheckBox_stat_ocean = \ self.display_stations(self.stations_ocean, DMISettingKeys.OCEANOBS_API_KEY, self.scrollAreaWidgetContents_10, invalid_api_key=invalid_oceanobs_api_key) + self.listCheckBox_station_climate_information = \ self.display_parameters(self.climatedata_parameters, DMISettingKeys.METOBS_API_KEY, self.scrollAreaWidgetContents_9, invalid_api_key=invalid_climate_api_key, use_radio_button=True) + self.listCheckBox_para_harmonie_igb_sf_edr = \ + self.display_parameters(self.harmonie_igb_sf_forecast_parameters, DMISettingKeys.FORECASTDATA_EDR_API_KEY, + self.scrollAreaWidgetContents_16, invalid_api_key=False) + self.listCheckBox_para_harmonie_nea_pl_edr = \ + self.display_parameters(self.harmonie_nea_pl_forecast_parameters, DMISettingKeys.FORECASTDATA_EDR_API_KEY, + self.scrollAreaWidgetContents_14, invalid_api_key=False) + self.listCheckBox_para_harmonie_igb_pl_edr = \ + self.display_parameters(self.harmonie_igb_pl_forecast_parameters, DMISettingKeys.FORECASTDATA_EDR_API_KEY, + self.scrollAreaWidgetContents_15, invalid_api_key=False) + self.listCheckBox_para_harmonie_nea_sf_edr = \ + self.display_parameters(self.harmonie_nea_sf_forecast_parameters, DMISettingKeys.FORECASTDATA_EDR_API_KEY, + self.scrollAreaWidgetContents_12, invalid_api_key=False) + self.listCheckBox_para_dkss_nsbs_edr = \ + self.display_parameters(self.dkss_nsbs_forecast_parameters, DMISettingKeys.FORECASTDATA_EDR_API_KEY, + self.scrollAreaWidgetContents_13, invalid_api_key=False) + self.listCheckBox_para_dkss_idw_edr = \ + self.display_parameters(self.dkss_idw_forecast_parameters, DMISettingKeys.FORECASTDATA_EDR_API_KEY, + self.scrollAreaWidgetContents_20, invalid_api_key=False) + self.listCheckBox_para_dkss_lf_edr = \ + self.display_parameters(self.dkss_lf_forecast_parameters, DMISettingKeys.FORECASTDATA_EDR_API_KEY, + self.scrollAreaWidgetContents_21, invalid_api_key=False) + self.listCheckBox_para_dkss_lb_edr = \ + self.display_parameters(self.dkss_lb_forecast_parameters, DMISettingKeys.FORECASTDATA_EDR_API_KEY, + self.scrollAreaWidgetContents_22, invalid_api_key=False) + self.listCheckBox_para_dkss_if_edr = \ + self.display_parameters(self.dkss_if_forecast_parameters, DMISettingKeys.FORECASTDATA_EDR_API_KEY, + self.scrollAreaWidgetContents_23, invalid_api_key=False) + self.listCheckBox_para_dkss_ws_edr = \ + self.display_parameters(self.dkss_ws_forecast_parameters, DMISettingKeys.FORECASTDATA_EDR_API_KEY, + self.scrollAreaWidgetContents_24, invalid_api_key=False) + self.listCheckBox_para_wam_edr = \ + self.display_parameters(self.wam_forecast_parameters, DMISettingKeys.FORECASTDATA_EDR_API_KEY, + self.scrollAreaWidgetContents_11, invalid_api_key=False) @staticmethod def generate_no_api_key_label(settings_key: DMISettingKeys): @@ -318,13 +437,17 @@ def display_parameters(self, parameters: Set[Parameter], settings_key: DMISettin parameter_layout.addWidget(DMIOpenDataDialog.generate_no_api_key_label(settings_key)) return checkboxes + # The different actions that use the objects defined earlier. + + # Enables or disables different radar types. def comp(self): self.stat_radar.setEnabled(False) self.scan_type.setEnabled(True) def pseud(self): self.stat_radar.setEnabled(True) self.scan_type.setEnabled(False) -# Disables or enables time in "Stations and parameters" + + # Disables or enables time in "Stations and parameters" def disable_time_oce(self): self.dateTimeEdit_3.setEnabled(False) self.dateTimeEdit_4.setEnabled(False) @@ -337,15 +460,22 @@ def disable_time(self): def enable_time(self): self.groupBox_25.setEnabled(True) self.groupBox_26.setEnabled(True) -# Changes pages when clicked + + # Changes pages when clicked def wamTab(self): self.para_stacked.setCurrentWidget(self.wam_page) def dkssTab(self): self.para_stacked.setCurrentWidget(self.dkss_page) - def depth_tab_dis(self): - self.groupBox_14.setEnabled(False) - def depth_tab_enabled(self): - self.groupBox_14.setEnabled(True) + def harmonieTab(self): + self.para_stacked.setCurrentWidget(self.harmonie_page) + def neaSfTab(self): + self.harm_para_stacked.setCurrentWidget(self.harm_nea_sf_para) + def neaPlTab(self): + self.harm_para_stacked.setCurrentWidget(self.harm_nea_pl_para) + def igbSfTab(self): + self.harm_para_stacked.setCurrentWidget(self.harm_igb_sf_para) + def igbPlTab(self): + self.harm_para_stacked.setCurrentWidget(self.harm_igb_pl_para) def infoStat(self): self.stackedWidget_3.setCurrentWidget(self.met_stat_page) def infoGrid10(self): @@ -360,29 +490,71 @@ def infoLight(self): self.stackedWidget_3.setCurrentWidget(self.light_page) def infoTide(self): self.stackedWidget_3.setCurrentWidget(self.tide_page) + def stat_typeR(self): + self.stackedWidget.setCurrentWidget(self.stat_clima) + self.stackedWidget_2.setCurrentWidget(self.stat_para) + def grid10_typeR(self): + self.stackedWidget.setCurrentWidget(self.grid_10) + self.stackedWidget_2.setCurrentWidget(self.grid_para) + def grid20_typeR(self): + self.stackedWidget.setCurrentWidget(self.grid_20) + self.stackedWidget_2.setCurrentWidget(self.grid_para) + def municipality_typeR(self): + self.stackedWidget.setCurrentWidget(self.municipality) + self.stackedWidget_2.setCurrentWidget(self.grid_para) + def country_typeR(self): + self.stackedWidget.setCurrentWidget(self.country) + self.stackedWidget_2.setCurrentWidget(self.grid_para) + def wamTab_grib(self): + self.para_stacked_2.setCurrentWidget(self.wam_page_2) + def dkssTab_grib(self): + self.para_stacked_2.setCurrentWidget(self.dkss_page_2) def nsbs_depth_tab(self): - self.stackedWidget_4.setCurrentWidget(self.nsbs_depth) + self.stacked_depth.setCurrentWidget(self.nsbs_depth) def idw_depth_tab(self): - self.stackedWidget_4.setCurrentWidget(self.idw_depth) + self.stacked_depth.setCurrentWidget(self.idw_depth) def ws_depth_tab(self): - self.stackedWidget_4.setCurrentWidget(self.ws_depth) + self.stacked_depth.setCurrentWidget(self.ws_depth) def if_depth_tab(self): - self.stackedWidget_4.setCurrentWidget(self.if_depth) + self.stacked_depth.setCurrentWidget(self.if_depth) def lf_depth_tab(self): - self.stackedWidget_4.setCurrentWidget(self.lf_depth) + self.stacked_depth.setCurrentWidget(self.lf_depth) def lb_depth_tab(self): - self.stackedWidget_4.setCurrentWidget(self.lb_depth) - - - -# Actions for buttons to go to dmi.dk + self.stacked_depth.setCurrentWidget(self.lb_depth) + def depth_tab_dis(self): + self.depth_group.setEnabled(False) + def depth_tab_enabled(self): + self.depth_group.setEnabled(True) + def idw_tab(self): + self.stackedWidget_4.setCurrentWidget(self.idw) + def nsbs_tab(self): + self.stackedWidget_4.setCurrentWidget(self.nsbs) + def lf_tab(self): + self.stackedWidget_4.setCurrentWidget(self.lf) + def lb_tab(self): + self.stackedWidget_4.setCurrentWidget(self.lb) + def ws_tab(self): + self.stackedWidget_4.setCurrentWidget(self.ws) + def if_tab(self): + self.stackedWidget_4.setCurrentWidget(self.isf) + + # Enables coordinates or BBOX + def enableCoordi(self): + self.coordi_line.setEnabled(True) + self.bbox_line.setEnabled(False) + def enableBBox(self): + self.coordi_line.setEnabled(False) + self.bbox_line.setEnabled(True) + + # Actions for buttons to go to dmi.dk def open_openData(self): webbrowser.open('https://confluence.govcloud.dk/display/FDAPI/Danish+Meteorological+Institute+-+Open+Data') def open_openData_2(self): webbrowser.open('https://confluence.govcloud.dk/display/FDAPI/Danish+Meteorological+Institute+-+Open+Data') def open_dmi_dk(self): webbrowser.open('https://www.dmi.dk/') -# Actions when saving as .csv + + # Actions when saving as .csv def browse_files_cli(self): fname = QFileDialog.getSaveFileName(self, 'Open File', 'C:') self.file_name_cli.setText(fname[0]) @@ -392,27 +564,15 @@ def browse_files_lig(self): def browse_files_oce(self): fname = QFileDialog.getSaveFileName(self, 'Open File', 'C:') self.file_name_oce.setText(fname[0]) -# Changing pages in Climate Data - def stat_typeR(self): - self.stackedWidget.setCurrentWidget(self.stat_clima) - self.stackedWidget_2.setCurrentWidget(self.stat_para) - def grid10_typeR(self): - self.stackedWidget.setCurrentWidget(self.grid_10) - self.stackedWidget_2.setCurrentWidget(self.grid_para) - def grid20_typeR(self): - self.stackedWidget.setCurrentWidget(self.grid_20) - self.stackedWidget_2.setCurrentWidget(self.grid_para) - def municipality_typeR(self): - self.stackedWidget.setCurrentWidget(self.municipality) - self.stackedWidget_2.setCurrentWidget(self.grid_para) - def country_typeR(self): - self.stackedWidget.setCurrentWidget(self.country) - self.stackedWidget_2.setCurrentWidget(self.grid_para) + def browse_files_fore(self): + fname = QFileDialog.getSaveFileName(self, 'Open File', 'C') + self.file_name_fore.setText(fname[0]) def browse_files_obs(self): fname = QFileDialog.getSaveFileName(self, 'Open File', 'C:') self.file_name_obs.setText(fname[0]) def run(self): + # The two lists used to store the users input parameters = [] stations = [] @@ -437,9 +597,12 @@ def run(self): elif dataName == 'Lightning Data': data_type = 'lightningdata' api_key = self.settings_manager.value(DMISettingKeys.LIGHTNINGDATA_API_KEY.value) - elif dataName == 'Forecast Data': + elif dataName == 'Forecast Data (Vector)': + data_type = 'forecastdata' + api_key = self.settings_manager.value(DMISettingKeys.FORECASTDATA_EDR_API_KEY.value) + elif dataName == 'Forecast Data (Raster)': data_type = 'forecastdata' - api_key = self.settings_manager.value(DMISettingKeys.FORECASTDATA_API_KEY.value) + api_key = self.settings_manager.value(DMISettingKeys.FORECASTDATA_GRIB_API_KEY.value) elif dataName == 'Stations and Parameters' and self.met_stat_info.isChecked(): data_type = 'stat_para_info' elif dataName == 'Stations and Parameters' and self.tide_info.isChecked(): @@ -472,13 +635,19 @@ def run(self): data_type2 = 'climateData' elif data_type == 'ocean_para_info': data_type2 = 'oceanObs' - elif data_type == 'forecastdata': - if self.wam_fore.isChecked(): + elif dataName == 'Forecast Data (Raster)': + if self.wam_fore_grib.isChecked(): + data_type2 = 'wam' + elif self.dkss_fore_grib.isChecked(): + data_type2 = 'dkss' + elif dataName == 'Forecast Data (Vector)': + if self.harm_fore.isChecked(): + data_type2 = 'harmonie' + elif self.wam_fore.isChecked(): data_type2 = 'wam' elif self.dkss_fore.isChecked(): data_type2 = 'dkss' - # Based on data_type2 the stationId, municipalityId or cellId will be assigned. if data_type2 == 'observation' and data_type == 'metObs': stat1 = 'stationId' @@ -493,25 +662,34 @@ def run(self): elif data_type2 == '20kmGridValue': stat1 = 'cellId' elif data_type2 == 'wam': - if self.danish_waters.isChecked(): + if self.danish_waters.isChecked() or self.danish_waters_2.isChecked(): fore_area = 'dw' - elif self.north_atlantic.isChecked(): + elif self.north_atlantic.isChecked() or self.north_atlantic_2.isChecked(): fore_area = 'natlant' - elif self.north_sea_baltic.isChecked(): + elif self.north_sea_baltic.isChecked() or self.north_sea_baltic_2.isChecked(): fore_area = 'nsb' elif data_type2 == 'dkss': - if self.north_sea_baltic_sea.isChecked(): + if self.north_sea_baltic_sea.isChecked() or self.north_sea_baltic_sea_2.isChecked(): fore_area = 'nsbs' - elif self.inner_danish_waters.isChecked(): + elif self.inner_danish_waters.isChecked() or self.inner_danish_waters_2.isChecked(): fore_area = 'idw' - elif self.wadden_sea.isChecked(): + elif self.wadden_sea.isChecked() or self.wadden_sea_2.isChecked(): fore_area = 'ws' - elif self.isefjord.isChecked(): + elif self.isefjord.isChecked() or self.isefjord_2.isChecked(): fore_area = 'if' - elif self.limfjord.isChecked(): + elif self.limfjord.isChecked() or self.limfjord_2.isChecked(): fore_area = 'lf' - elif self.little_belt.isChecked(): + elif self.little_belt.isChecked() or self.little_belt_2.isChecked(): fore_area = 'lb' + elif data_type2 == 'harmonie': + if self.nea_sf_area.isChecked(): + fore_area = 'nea_sf' + elif self.nea_pl_area.isChecked(): + fore_area = 'nea_pl' + elif self.igb_sf_area.isChecked(): + fore_area = 'igb_sf' + elif self.igb_pl_area.isChecked(): + fore_area = 'igb_pl' # Oceanographic parameters if dataName == 'Oceanographic Observations': @@ -562,10 +740,10 @@ def run(self): # Municipality ID if data_type2 == 'municipalityValue': - for munic_id in munic: + for munic_id in munic_id_name: qt_checkbox_widget = self.listCheckBox_municipalityId[munic_id] if qt_checkbox_widget.isChecked(): - stations.append(munic_id) + stations.append(munic_id[-4:]) qt_checkbox_widget.setChecked(False) # Grid, municipality and country parameters @@ -600,31 +778,88 @@ def run(self): parameters.append(parameter) qt_checkbox_widget.setChecked(False) - if data_type2 == 'wam': - wam_para = ['wind_speed_10', 'wind_direction_10', 'sig_wave_height', 'dom_wave_period', 'mean_wave_period', - 'mean_zero_wave_period', 'mean_wave_dir', 'sig_height_wind_waves_sea', 'mean_period_wind_wave_sea', - 'mean_dir_wind_wave_sea', 'sig_height_swell', 'mean_period_swell', 'mean_dir_swell', - 'benjamin_index'] - wam_para_band = list(range(1, 15)) - para_fore_dict_wam = dict(zip(wam_para, wam_para_band)) - for fore_para in para_fore_dict_wam: - qt_checkbox_widget = getattr(self, fore_para) - if qt_checkbox_widget.isChecked(): - parameters.append(fore_para) - qt_checkbox_widget.setChecked(False) - - if data_type2 == 'dkss': + # Forecast WAM parameters (GRIB) + if data_type2 == 'wam' and dataName == 'Forecast Data (Raster)': + wam_para = ['wind_speed_10', 'wind_direction_10', 'sig_wave_height', 'dom_wave_period', + 'mean_wave_period_2', + 'mean_zero_wave_period', 'mean_wave_dir_2', 'sig_height_wind_waves_sea', + 'mean_period_wind_wave_sea', + 'mean_dir_wind_wave_sea', 'sig_height_swell', 'mean_period_swell', 'mean_dir_swell', + 'benjamin_index'] + wam_para_band = list(range(1, 15)) + para_fore_dict_wam = dict(zip(wam_para, wam_para_band)) + for fore_para in para_fore_dict_wam: + qt_checkbox_widget = getattr(self, fore_para) + if qt_checkbox_widget.isChecked(): + parameters.append(fore_para) + qt_checkbox_widget.setChecked(False) + + # Forecast DKSS parameters (GRIB) + if data_type2 == 'dkss' and dataName == 'Forecast Data (Raster)': nsbs_para = ['dev_sea_mean', 'u_comp_wind', 'v_comp_wind', 'u_comp_cur', 'v_comp_cur', - 'water_temp', 'salinity', 'ice_thick', 'ice_conc', 'u_comp_cur_', + 'water_temp', 'salinity_2', 'ice_thick', 'ice_conc', 'u_comp_cur_', 'v_comp_cur_', 'water_temp_', 'salinity_'] nsbs_para_band = list(range(1, 10)) para_fore_dict_nsbs = dict(zip(nsbs_para[0:9], nsbs_para_band)) for fore_para in nsbs_para: - qt_checkbox_widget = getattr(self, fore_para) - if qt_checkbox_widget.isChecked(): - parameters.append(fore_para) - qt_checkbox_widget.setChecked(False) - + qt_checkbox_widget = getattr(self, fore_para) + if qt_checkbox_widget.isChecked(): + parameters.append(fore_para) + qt_checkbox_widget.setChecked(False) + + # Forecast HARMONIE, DKSS and WAM (EDR) + if data_type2 == 'harmonie' or data_type2 == 'dkss' or data_type2 == 'wam': + if fore_area == 'nea_sf': + parameterListForecast = self.harmonie_nea_sf_forecast_parameters + listCheckBoxForecast = self.listCheckBox_para_harmonie_nea_sf_edr + + elif fore_area == 'nea_pl': + parameterListForecast = self.harmonie_nea_pl_forecast_parameters + listCheckBoxForecast = self.listCheckBox_para_harmonie_nea_pl_edr + + elif fore_area == 'igb_sf': + parameterListForecast = self.harmonie_igb_sf_forecast_parameters + listCheckBoxForecast = self.listCheckBox_para_harmonie_igb_sf_edr + + elif fore_area == 'igb_pl': + parameterListForecast = self.harmonie_igb_pl_forecast_parameters + listCheckBoxForecast = self.listCheckBox_para_harmonie_igb_pl_edr + + elif fore_area == 'nsbs': + parameterListForecast = self.dkss_nsbs_forecast_parameters + listCheckBoxForecast = self.listCheckBox_para_dkss_nsbs_edr + + elif fore_area == 'idw': + parameterListForecast = self.dkss_idw_forecast_parameters + listCheckBoxForecast = self.listCheckBox_para_dkss_idw_edr + + elif fore_area == 'lf': + parameterListForecast = self.dkss_lf_forecast_parameters + listCheckBoxForecast = self.listCheckBox_para_dkss_lf_edr + + elif fore_area == 'lb': + parameterListForecast = self.dkss_lf_forecast_parameters + listCheckBoxForecast = self.listCheckBox_para_dkss_lf_edr + + elif fore_area == 'if': + parameterListForecast = self.dkss_if_forecast_parameters + listCheckBoxForecast = self.listCheckBox_para_dkss_if_edr + + elif fore_area == 'ws': + parameterListForecast = self.dkss_ws_forecast_parameters + listCheckBoxForecast = self.listCheckBox_para_dkss_ws_edr + + elif data_type2 == 'wam': + parameterListForecast = self.wam_forecast_parameters + listCheckBoxForecast = self.listCheckBox_para_wam_edr + + for para in parameterListForecast: + qt_checkbox_widget = listCheckBoxForecast[para] + if qt_checkbox_widget.isChecked(): + para = para.replace('_','-') + parameters.append(para) + qt_checkbox_widget.setChecked(False) + # Information for stations. The list of stations is based on climateData and NOT metObs if dataName == 'Stations and Parameters' and data_type2 == 'climateData': for parameter in self.climatedata_parameters: @@ -632,6 +867,7 @@ def run(self): if qt_checkbox_widget.isChecked(): parameters.append(parameter) qt_checkbox_widget.setChecked(False) + if dataName == 'Stations and Parameters' and data_type2 == 'oceanObs': ocean_parameters = ['sea_reg_info', 'sealev_dvr_info', 'sealev_ln_info', 'tw_info'] for oce_para in ocean_parameters: @@ -648,7 +884,7 @@ def run(self): if qt_checkbox_widget.isChecked(): radar_stations_it.append(radar_stat[1:]) qt_checkbox_widget.setChecked(False) - # Datetime + # Changes the format of the datetime to make it compatible for the URL calls. # The format by QT is yyyy:m:d h:m:s and the format needed for URL is yyyy:mm:ddThh:mm:ssZ if dataName == 'Meteorological Observations': @@ -671,7 +907,11 @@ def run(self): start_datetime = self.start_date5.dateTime().toString(Qt.ISODate) + 'Z' end_datetime = self.end_date5.dateTime().toString(Qt.ISODate) + 'Z' - elif dataName == 'Forecast Data': + elif dataName == 'Forecast Data (Vector)': + start_datetime = self.datetime_fore_start.dateTime().toString(Qt.ISODate) + 'Z' + end_datetime = self.datetime_fore_end.dateTime().toString(Qt.ISODate) + 'Z' + + elif dataName == 'Forecast Data (Raster)': start_datetime = self.datetime_fore_start.dateTime().toString(Qt.ISODate) + 'Z' end_datetime = self.datetime_fore_end.dateTime().toString(Qt.ISODate) + 'Z' @@ -742,17 +982,16 @@ def run(self): stat_and_res = {stat1 : stat, 'timeResolution': res} params.update(stat_and_res) -# No stations for country values. + # No stations for country values. elif dataName == 'Climate Data' and data_type2 == 'countryValue': res_country = {'timeResolution': res} params.update(res_country) else: observed_w_stat = {stat1 : stat} params.update(observed_w_stat) - r = requests.get(url, params=params) - print(r.url) + r = requests.get(url, params=params) + print(r, r.url) json = r.json() - #df = json_normalize(json['features']) # Makes sure that data gets a return. If no numbers returned then shows a warning box. # r_code represents the status code. r_code = r.status_code @@ -893,7 +1132,7 @@ def run(self): elif self.pseudo.isChecked(): params.update({'stationId': radar_stations_it}) r = requests.get(url, params=params) - print(r.url) + print(r, r.url) r_code = r.status_code json = r.json() if r_code == 403: @@ -951,7 +1190,7 @@ def run(self): 'limit' : '300000'} # Did the user choose the BBOX? if self.bbox_lightning.text() != '': - params.update({'bbox': self.bbox_lig.text()}) + params.update({'bbox': self.bbox_lightning.text()}) # Did the user choose any specific lightning type? if self.cloud_to_g_pos.isChecked(): params.update({'type': '1'}) @@ -966,7 +1205,7 @@ def run(self): name = 'Lightning' # URL creation r = requests.get(url, params=params) - print(r.url) + print(r, r.url) json = r.json() r_code = r.status_code if r_code == 403: @@ -1004,38 +1243,118 @@ def run(self): else: df.to_csv(self.file_name_lig.text() + '.csv', index=False) self.file_name_lig.clear() - # Forecast data - if dataName == 'Forecast Data': + + # ForecastEDR data + if dataName == 'Forecast Data (Vector)': + if self.bbox_harm.isChecked(): + position_res = 'cube' + elif self.coordi_harm.isChecked(): + position_res = 'position' + url = 'https://dmigw.govcloud.dk/v1/forecastedr/collections/' + data_type2 + '_' + fore_area + '/' + position_res + '?' + params = {'api-key': api_key, + 'datetime': datetime, + 'limit': '300000', + 'f': 'GeoJSON',} + + if self.bbox_harm.isChecked(): + # This variable is used to decide whether or not QGIS should try to add data. + # returned_data = 1 then it proceeds, returned_data = 0 it stops. + returned_data = '1' + bbox_cordi = self.bbox_line.text() + if ' ' in bbox_cordi: + bbox_cordi = bbox_cordi.replace(' ', '') + params.update({'bbox': bbox_cordi}) + if bbox_cordi == '': + QMessageBox.warning(self, self.tr("DMI Open Data"), + self.tr('Please fill out the BBox.')) + returned_data = '0' + + + elif self.coordi_harm.isChecked(): + returned_data = '1' + point_coordi = self.coordi_line.text() + if ' ' in point_coordi: + point_coordi = point_coordi.replace(' ', '') + # The API does not accept comma sepperation, which is why the comma is changed to a space. + point_coordi = point_coordi.replace(',',' ') + params.update({'coords': 'POINT(' + point_coordi + ')'}) + if point_coordi == '': + QMessageBox.warning(self, self.tr("DMI Open Data"), + self.tr('Please fill out the Coordinates.')) + returned_data = '0' + + + # A parameter must be given. Otherwise QGIS will try to import all parameters, which is rarely needed. + if len(parameters) > 0 and returned_data != '0': + params.update({'parameter-name': parameters}) + returned_data = '1' + elif len(parameters) == 0: + QMessageBox.warning(self, self.tr("DMI Open Data"), + self.tr('Please select a parameter.')) + returned_data = '0' + + if returned_data != '0': + r = requests.get(url, params=params) + print(r, r.url) + json = r.json() + df = json_normalize(json['features']) + # Remove collumns that are not needed. + df = df.drop(['type', 'geometry.type'], axis=1) + vl = QgsVectorLayer("Point", data_type2 + ' ' + fore_area, "memory") + # If the user wants an overview of the data, the df.head is printed with all columns visible. + pd.set_option('display.max_columns', None) + pr = vl.dataProvider() + vl.startEditing() + for head in df: + if head == 'properties.step': + pr.addAttributes([QgsField(head, QVariant.DateTime)]) + if head != 'geometry.coordinates': + pr.addAttributes([QgsField(head, QVariant.Double)]) + for row in df.itertuples(): + f = QgsFeature() + f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(row[1][0], row[1][1]))) + vl.updateFields() + params_list_to_feat = list(row[2:len(df.columns)+1]) + f.setAttributes(params_list_to_feat) + vl.addFeature(f) + vl.updateExtents() + vl.commitChanges() + QgsProject.instance().addMapLayer(vl) + iface.zoomToActiveLayer() + + if self.file_name_fore.text() != '': + df.to_csv(self.file_name_fore.text() + '.csv', index=False) + + # Forecast Data (GRIB) + if dataName == 'Forecast Data (Raster)': root = QgsProject.instance().layerTreeRoot() layer_group = root.insertGroup(0, 'Forecast' + datetime) temp = mkdtemp(suffix='_forecast-files') url = 'https://dmigw.govcloud.dk/v1/' + data_type + '/collections/' + data_type2 + '_' + fore_area + '/items' params = {'api-key': api_key, - 'datetime': datetime, - 'limit': '300000'} - if self.bbox_fore.text() != '': - params.update({'bbox': self.bbox_fore.text()}) + 'datetime': datetime, + 'limit': '300000'} r = requests.get(url, params=params) print(r, r.url) json = r.json() - latest_model_run = sorted(json['features'], key=lambda feature: feature['properties']['modelRun'])[-1]['properties']['modelRun'] - print(latest_model_run) - for feature in filter(lambda feature: feature['properties']['modelRun'] == latest_model_run, json['features']): + latest_model_run = \ + sorted(json['features'], key=lambda feature: feature['properties']['modelRun'])[-1]['properties'][ + 'modelRun'] + for feature in filter(lambda feature: feature['properties']['modelRun'] == latest_model_run, + json['features']): downloadurl = feature['asset']['data']['href'] downloaddata = requests.get(downloadurl) id = feature['id'] - print(id) tempfile = os.path.join(temp, id) if not os.path.isfile(tempfile): with open(tempfile, 'wb') as fd: for chunk in downloaddata.iter_content(): fd.write(chunk) layer = QgsRasterLayer(tempfile) - #if self.all_para_wam.isChecked() == False or self.all_para_dkss.isChecked() == False: if data_type2 == 'wam': band_par = para_fore_dict_wam[parameters[0]] - print(band_par) elif data_type2 == 'dkss': + # Checks if the chosen parameter is a parameter that can be viewed at different depths if parameters[0] in depth_para_dkss: if fore_area == 'nsbs': depth = int(self.depth_box_nsbs.currentText()) @@ -1119,21 +1438,25 @@ def run(self): layer.setRenderer(renderer) layer.renderer().setContrastEnhancement(myEnhancement) - # Changes the name if len(parameters) > 0: - if self.wam_fore.isChecked(): - layer.setName(data_type2 + ' ' + fore_area + ' ' + parameters[0] + ' ' + feature['properties']['datetime']) + if self.wam_fore_grib.isChecked(): + layer.setName( + data_type2 + ' ' + fore_area + ' ' + parameters[0] + ' ' + feature['properties'][ + 'datetime']) elif self.dkss_fore.isChecked() and parameters[0] in depth_para_dkss: - layer.setName(data_type2 + ' ' + fore_area + ' ' + parameters[0] + ' ' + str(depth) + 'm ' + feature['properties']['datetime']) + layer.setName(data_type2 + ' ' + fore_area + ' ' + parameters[0] + ' ' + str(depth) + 'm ' + + feature['properties']['datetime']) elif self.dkss_fore.isChecked() and parameters[0] not in depth_para_dkss: - layer.setName(data_type2 + ' ' + fore_area + ' ' + parameters[0] + ' ' + feature['properties']['datetime']) - elif len(parameters) == 0: - layer.setName(data_type2 + ' ' + fore_area + ' ' + 'All parameters ' + feature['properties']['datetime']) + layer.setName( + data_type2 + ' ' + fore_area + ' ' + parameters[0] + ' ' + feature['properties'][ + 'datetime']) # Adds the layer to the map project = QgsProject.instance() project.addMapLayer(layer, addToLegend=False) layer_group.insertLayer(-1, layer) + + # Information about stations and parameters if dataName == 'Stations and Parameters': if self.met_stat_info.isChecked(): @@ -1169,7 +1492,7 @@ def run(self): elif self.radioButton_19.isChecked() and self.radioButton_22.isChecked(): params.update({'datetime': datetime}) r = requests.get(url, params=params) - print(r.url) + print(r, r.url) json = r.json() r_code = r.status_code if r_code == 403: diff --git a/DMI_Open_Data_dialog_base.ui b/DMI_Open_Data_dialog_base.ui index f04b744..4a822aa 100644 --- a/DMI_Open_Data_dialog_base.ui +++ b/DMI_Open_Data_dialog_base.ui @@ -10,7 +10,7 @@ 0 0 1345 - 528 + 598 @@ -134,7 +134,7 @@ 0 0 624 - 246 + 282 @@ -165,7 +165,7 @@ 0 0 623 - 246 + 282 @@ -353,7 +353,7 @@ - 1 + 0 @@ -367,8 +367,8 @@ 0 0 - 98 - 28 + 628 + 235 @@ -389,8 +389,8 @@ 0 0 - 628 - 204 + 98 + 28 @@ -407,7 +407,7 @@ - 0 + 3 @@ -421,8 +421,8 @@ 0 0 - 627 - 204 + 98 + 28 @@ -487,8 +487,8 @@ 0 0 - 98 - 28 + 627 + 235 @@ -990,7 +990,7 @@ 0 0 625 - 248 + 284 @@ -1029,9 +1029,9 @@ - Forecast Data + Forecast Data (Vector) - + @@ -1079,9 +1079,16 @@ Model - + + + + + Weather Model (HARMONIE) + + + @@ -1104,8 +1111,181 @@ - 0 + 2 + + + + + + + + + 0 + 0 + + + + Parameters + + + + + + + 0 + 0 + + + + 0 + + + + + + + + 0 + 0 + + + + true + + + + + 0 + 0 + 599 + 149 + + + + + + + + + + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + + + + + + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + + + + + + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + + + + + + + + + + + + + + 0 + 0 + + + + Areas + + + + + + Northwestern Europe Surface (NEA SF) + + + + + + + Northwestern Europe Pressure Level (NEA PL) + + + + + + + Iceland Greenland Surface (IGB SF) + + + + + + + Iceland Greenland Pressure Level (IGB PL) + + + + + + + + + + @@ -1132,11 +1312,465 @@ 0 0 - 604 - 348 + 617 + 159 + + + + + + + + + + + Areas + + + + + + Danish Waters + + + + + + + North Atlantic + + + + + + + North Sea-Baltic + + + + + + + + + + + + + + + + + + + + + Parameters + + + + + + 2 + + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + + + + + + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + + + + + + + + + + true + + + + + 0 + 0 + 599 + 149 + + + + + + + + + + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + + + + + + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + + + + + + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + + + + + + + + + + + + + + 0 + 0 + + + + Areas + + + + + + North Sea Baltic Sea + + + + + + + Inner Danish Waters + + + + + + + Wadden Sea + + + + + + + Isefjord + + + + + + + Limfjord + + + + + + + Little Belt + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + Coordinate or BBox + + + + + + + + BBox + + + + + + + E.g. 8.07,54.55,15.17,57.76 + + + + + + + + + + + Coordinate + + + + + + + E.g. 13.58,55.06 + + + + + + + + + + + + + 0 + 0 + + + + Save as .csv file also (Optional) + + + + + + + + + + + Browse + + + + + + + + + + + + + + + Forecast Data (Raster) + + + + + + + + + 0 + 0 + + + + Start date and time + + + + + + true + + + + + + + + + + End date and time + + + + + + true + + + + + + + + + + + + Model + + + + + + + + Wave Model (WAM) + + + + + + + Strom Surge Model (DKSS) + + + + + + + + + + + + 1 + + + + + + + + + Parameters + + + + + + + 0 + 0 + + + + true + + + + + 0 + 0 + 399 + 418 + + + @@ -1166,7 +1800,7 @@ - + Mean wave period @@ -1180,7 +1814,7 @@ - + Mean wave direction @@ -1243,27 +1877,27 @@ - + Areas - + - + Danish Waters - + North Atlantic - + North Sea-Baltic @@ -1275,45 +1909,22 @@ - - - - - - 0 - 0 - - - - BBox - - - - - - E.g. 8.0786,54.5576,15.1712,57.7664 - - - - - - - + - - + + - + - + Parameters - + 0 @@ -1323,16 +1934,16 @@ true - + 0 0 - 251 - 324 + 600 + 389 - + @@ -1376,7 +1987,7 @@ - + Salinity @@ -1432,48 +2043,48 @@ - + Areas - + - + North Sea Baltic Sea - + Inner Danish Waters - + Wadden Sea - + Isefjord - + Limfjord - + Little Belt @@ -1485,20 +2096,20 @@ - + - + Depth (meters) - + - + 1 - + @@ -1756,7 +2367,7 @@ - + @@ -2024,7 +2635,7 @@ - + @@ -2142,7 +2753,7 @@ - + @@ -2200,7 +2811,7 @@ - + @@ -2313,7 +2924,7 @@ - + @@ -2535,24 +3146,6 @@ - - - - - 0 - 0 - - - - BBox - - - - - - - - @@ -2587,7 +3180,7 @@ - 1 + 0 @@ -2651,8 +3244,8 @@ 0 0 - 98 - 28 + 295 + 381 @@ -2923,17 +3516,16 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:12pt; font-weight:400; font-style:normal;"> <p align="center" style=" margin-top:18px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; font-weight:600;">Plugin for DMIs Open Data </span></p> -<p style=" margin-top:14px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Before starting</span></p> +<p style=" margin-top:14px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Before starting</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Documentation and more information about DMI Open Data can be found </span><a href="https://confluence.govcloud.dk/display/FDAPI/Danish+Meteorological+Institute+-+Open+Data"><span style=" font-size:11pt; text-decoration: underline; color:#0000ff;">here</span></a><span style=" font-size:11pt;">. This guide will only briefly cover the plugin - not the data, stations etc.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">A thorough guide of how to use this plugin, along with examples, can be found </span><a href="https://github.com/dmidk/Open-Data-QGIS-plugin/blob/master/Guide.md"><span style=" font-size:11pt; text-decoration: underline; color:#0000ff;">here</span></a><span style=" font-size:11pt;">. </span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">The plugin allows the user to easily import data from DMIs Open Data from Meteorological Observations (metObs), Climate Data (climateData), Lightning Data (lightningData), Radar Data (radarData) and Oceanographic Observations (oceanObs). At each tab, the users API-key has to be inserted in order to get data. An API-key can be created </span><a href="https://confluence.govcloud.dk/display/FDAPI/User+Creation"><span style=" font-size:11pt; text-decoration: underline; color:#0000ff;">here</span></a><span style=" font-size:11pt;">.</span></p> -<p style=" margin-top:14px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">How to use this plugin</span></p> +<p style=" margin-top:14px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to use this plugin</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">In order to get data, an API Key must be configured in QGIS settings menu. To configure API keys, please go to Settings -&gt; Options -&gt; DMI Open Data. Note that each type of data requires one specific API Key corresponding to that UI. <br />After the API Key has been configured in settings, stations and parameters will be accessible, and the plugin will work as intended. </span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Things to note when using the plugin: </span></p> -<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-size:11pt;" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Maximum amount of parameters available is 7.</li> -<li style=" font-size:11pt;" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Internet is neccessary in order to open the plugin and get data.</li> +<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-size:11pt;" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Internet is neccessary in order to open the plugin and get data.</li> <li style=" font-size:11pt;" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Sort the data in a manner that your QGIS can handle. Otherwise there is a risk of crashing.</li> <li style=" font-size:11pt;" style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Be sure to read about the stations and parameters, as not all stations measure all parameters. A list of meteorological stations and their associated parameters can also be found <a href="https://confluence.govcloud.dk/pages/viewpage.action?pageId=53086560"><span style=" text-decoration: underline; color:#0000ff;">here</span></a>.</li></ul> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">If you have any questions about the plugin or DMI Open Data then please contact us. </span></p> diff --git a/Guide.md b/Guide.md index 1a848de..05b47e4 100644 --- a/Guide.md +++ b/Guide.md @@ -95,11 +95,25 @@ The output is also the same as Meteorological Observations and the fields includ ![Oceanographic Observations](guide%20image/ocean.png) -## Forecast Data +## Forecast Data (Vector) - About -Forecast data allows the user to import data from DMIs Forecast models. 4 models will be made available: Weather Model (Harmonie), Wave Model (WAM), Storm Surge Model (DKSS) and Arctic Sea Ice Model (HYCOM-CICE). In version 0.1 of the plugin, only WAM and DKSS is available. When the two remaining models are released, they will also be included in the plugin. +Forecast data allows the user to import data from DMIs 3 Forecast models: HARMONIE (weather model), WAM (Wave model) and DKSS (Strom Surge model). + - Usage + +To choose between the different models, use the radio button. Each page has different parameters, areas and specifications. You can specify an area of interest, either by getting the closest point to a specified coordinate, or by defining a bounding box. Read more about forecast data [here](https://confluence.govcloud.dk/pages/viewpage.action?pageId=76155038). + - Output +The output is one or more points that contains the parameters chosen and a timestamp. + + +![Forecast Data](guide%20image/forecast_vector.png) + +## Forecast Data (Raster) + + - About + +Forecast data allows the user to import data from DMIs Forecast models. 2 models are available: Wave Model (WAM) and Storm Surge Model (DKSS). In version 0.1 of the plugin, only WAM and DKSS is available. When the two remaining models are released, they will also be included in the plugin. - Usage To choose between the different models, use the radio button. Each page has different parameters, areas and specifications. It is not possible to choose more than one parameter, as the output is all parameters in one layer. Read more about forecast data [here](https://confluence.govcloud.dk/display/FDAPI/Forecast+Data). @@ -107,7 +121,7 @@ To choose between the different models, use the radio button. Each page has diff The output is one layer with all parameters, where the chosen parameter is displayed. In the layer symbology, you can choose between all parameters and depths (depths is only available for DKSS) by clicking on another band. Each band thereby represent a parameter and a depth, that can be visualized by clicking on it. -![Forecast Data](guide%20image/forecast.png) +![Forecast Data](guide%20image/forecast_raster.png) ## Stations and Parameters diff --git a/api/edr_parameters.py b/api/edr_parameters.py new file mode 100644 index 0000000..0cb5fce --- /dev/null +++ b/api/edr_parameters.py @@ -0,0 +1,37 @@ +from typing import Tuple, Dict, List + +import requests +from enum import Enum + +ParameterId = str +ParameterDescription = str +ParameterInfo = Tuple[ParameterId, ParameterDescription] + +class EDRForecastCollection(Enum): + collection: str + + HARMONIE_NEA_SF = 'harmonie_nea_sf' + HARMONIE_NEA_PL = 'harmonie_nea_pl' + HARMONIE_IGB_SF = 'harmonie_igb_sf' + HARMONIE_IGB_PL = 'harmonie_igb_pl' + DKSS_NSBS = 'dkss_nsbs' + DKSS_IDW = 'dkss_idw' + DKSS_IF = 'dkss_if' + DKSS_WS = 'dkss_ws' + DKSS_LF = 'dkss_lf' + DKSS_LB = 'dkss_lb' + WAM_DW = 'wam_dw' + WAM_NSB = 'wam_nsb' + WAM_NATLANT = 'wam_natlant' + +def get_forecast_parameters(forecast_collection: EDRForecastCollection, api_key: str) -> List[ParameterInfo]: + edr_params = {'api-key': api_key} + forecast_para_request = requests.get( + f'https://dmigw.govcloud.dk/v1/forecastedr/collections/{forecast_collection.value}', + params=edr_params + ) + forecast_metadata = forecast_para_request.json() + parameters = [] + for parameter_id, parameter_metadata in forecast_metadata['parameter_names'].items(): + parameters.append((parameter_id, parameter_metadata['description'])) + return parameters diff --git a/guide image/forecast.png b/guide image/forecast_raster.png similarity index 100% rename from guide image/forecast.png rename to guide image/forecast_raster.png diff --git a/guide image/forecast_vector.png b/guide image/forecast_vector.png new file mode 100644 index 0000000..260cfe1 Binary files /dev/null and b/guide image/forecast_vector.png differ diff --git a/para_munic_grid.py b/para_munic_grid.py index 70b1034..966f538 100644 --- a/para_munic_grid.py +++ b/para_munic_grid.py @@ -6,7 +6,6 @@ grid10 = ['10km_605_65', '10km_605_66', '10km_605_68', '10km_605_69', '10km_606_60', '10km_606_61', '10km_606_63', '10km_606_64', '10km_606_65', '10km_606_66', '10km_606_67', '10km_606_68', '10km_606_69', '10km_607_51', '10km_607_52', '10km_607_54', '10km_607_59', '10km_607_60', '10km_607_61', '10km_607_62', '10km_607_63', '10km_607_64', '10km_607_65', '10km_607_66', '10km_607_67', '10km_607_68', '10km_607_69', '10km_608_47', '10km_608_48', '10km_608_49', '10km_608_50', '10km_608_51', '10km_608_52', '10km_608_53', '10km_608_54', '10km_608_55', '10km_608_56', '10km_608_57', '10km_608_58', '10km_608_59', '10km_608_60', '10km_608_61', '10km_608_62', '10km_608_63', '10km_608_64', '10km_608_65', '10km_608_66', '10km_608_67', '10km_608_68', '10km_608_69', '10km_608_70', '10km_609_47', '10km_609_48', '10km_609_49', '10km_609_50', '10km_609_51', '10km_609_52', '10km_609_53', '10km_609_54', '10km_609_55', '10km_609_56', '10km_609_57', '10km_609_58', '10km_609_59', '10km_609_60', '10km_609_61', '10km_609_62', '10km_609_63', '10km_609_64', '10km_609_65', '10km_609_66', '10km_609_67', '10km_609_68', '10km_609_69', '10km_609_70', '10km_609_71', '10km_609_72', '10km_610_46', '10km_610_47', '10km_610_48', '10km_610_49', '10km_610_50', '10km_610_51', '10km_610_52', '10km_610_53', '10km_610_54', '10km_610_55', '10km_610_56', '10km_610_57', '10km_610_58', '10km_610_59', '10km_610_60', '10km_610_61', '10km_610_62', '10km_610_65', '10km_610_66', '10km_610_67', '10km_610_68', '10km_610_69', '10km_610_70', '10km_610_71', '10km_610_72', '10km_611_46', '10km_611_47', '10km_611_48', '10km_611_49', '10km_611_50', '10km_611_51', '10km_611_52', '10km_611_53', '10km_611_54', '10km_611_56', '10km_611_57', '10km_611_58', '10km_611_59', '10km_611_60', '10km_611_61', '10km_611_62', '10km_611_63', '10km_611_65', '10km_611_66', '10km_611_67', '10km_611_68', '10km_611_69', '10km_611_70', '10km_611_86', '10km_611_87', '10km_611_88', '10km_611_89', '10km_612_47', '10km_612_48', '10km_612_49', '10km_612_50', '10km_612_51', '10km_612_52', '10km_612_53', '10km_612_54', '10km_612_55', '10km_612_56', '10km_612_57', '10km_612_58', '10km_612_59', '10km_612_60', '10km_612_61', '10km_612_63', '10km_612_64', '10km_612_65', '10km_612_66', '10km_612_67', '10km_612_68', '10km_612_69', '10km_612_70', '10km_612_71', '10km_612_86', '10km_612_87', '10km_612_88', '10km_612_89', '10km_613_46', '10km_613_47', '10km_613_48', '10km_613_49', '10km_613_50', '10km_613_51', '10km_613_52', '10km_613_53', '10km_613_54', '10km_613_55', '10km_613_56', '10km_613_57', '10km_613_58', '10km_613_59', '10km_613_60', '10km_613_61', '10km_613_63', '10km_613_64', '10km_613_65', '10km_613_66', '10km_613_67', '10km_613_68', '10km_613_69', '10km_613_70', '10km_613_71', '10km_613_86', '10km_613_87', '10km_613_88', '10km_614_45', '10km_614_46', '10km_614_47', '10km_614_48', '10km_614_49', '10km_614_50', '10km_614_51', '10km_614_52', '10km_614_53', '10km_614_54', '10km_614_55', '10km_614_56', '10km_614_57', '10km_614_58', '10km_614_59', '10km_614_60', '10km_614_61', '10km_614_63', '10km_614_64', '10km_614_65', '10km_614_66', '10km_614_67', '10km_614_68', '10km_614_69', '10km_614_70', '10km_614_71', '10km_614_86', '10km_614_89', '10km_615_44', '10km_615_45', '10km_615_46', '10km_615_47', '10km_615_48', '10km_615_49', '10km_615_50', '10km_615_51', '10km_615_52', '10km_615_53', '10km_615_54', '10km_615_55', '10km_615_56', '10km_615_57', '10km_615_58', '10km_615_59', '10km_615_60', '10km_615_61', '10km_615_63', '10km_615_64', '10km_615_65', '10km_615_66', '10km_615_67', '10km_615_68', '10km_615_69', '10km_615_70', '10km_616_44', '10km_616_45', '10km_616_46', '10km_616_47', '10km_616_48', '10km_616_49', '10km_616_50', '10km_616_51', '10km_616_52', '10km_616_53', '10km_616_54', '10km_616_55', '10km_616_57', '10km_616_58', '10km_616_60', '10km_616_63', '10km_616_64', '10km_616_65', '10km_616_66', '10km_616_67', '10km_616_68', '10km_616_69', '10km_616_70', '10km_616_71', '10km_616_72', '10km_616_73', '10km_617_44', '10km_617_45', '10km_617_46', '10km_617_47', '10km_617_48', '10km_617_49', '10km_617_50', '10km_617_51', '10km_617_52', '10km_617_53', '10km_617_54', '10km_617_55', '10km_617_56', '10km_617_58', '10km_617_62', '10km_617_63', '10km_617_64', '10km_617_65', '10km_617_66', '10km_617_67', '10km_617_68', '10km_617_69', '10km_617_70', '10km_617_71', '10km_617_72', '10km_617_73', '10km_618_44', '10km_618_45', '10km_618_46', '10km_618_47', '10km_618_48', '10km_618_49', '10km_618_50', '10km_618_51', '10km_618_52', '10km_618_53', '10km_618_54', '10km_618_55', '10km_618_56', '10km_618_57', '10km_618_58', '10km_618_59', '10km_618_60', '10km_618_64', '10km_618_65', '10km_618_66', '10km_618_67', '10km_618_68', '10km_618_69', '10km_618_70', '10km_618_71', '10km_618_72', '10km_619_44', '10km_619_45', '10km_619_46', '10km_619_47', '10km_619_48', '10km_619_49', '10km_619_50', '10km_619_51', '10km_619_52', '10km_619_53', '10km_619_54', '10km_619_55', '10km_619_56', '10km_619_57', '10km_619_59', '10km_619_60', '10km_619_63', '10km_619_64', '10km_619_65', '10km_619_66', '10km_619_67', '10km_619_68', '10km_619_69', '10km_619_70', '10km_619_71', '10km_619_72', '10km_620_44', '10km_620_45', '10km_620_46', '10km_620_47', '10km_620_48', '10km_620_49', '10km_620_50', '10km_620_51', '10km_620_52', '10km_620_53', '10km_620_54', '10km_620_55', '10km_620_56', '10km_620_57', '10km_620_58', '10km_620_59', '10km_620_64', '10km_620_65', '10km_620_66', '10km_620_67', '10km_620_68', '10km_620_69', '10km_620_70', '10km_620_71', '10km_620_72', '10km_621_44', '10km_621_45', '10km_621_46', '10km_621_47', '10km_621_48', '10km_621_49', '10km_621_50', '10km_621_51', '10km_621_52', '10km_621_53', '10km_621_54', '10km_621_55', '10km_621_56', '10km_621_57', '10km_621_59', '10km_621_68', '10km_621_69', '10km_621_70', '10km_621_71', '10km_621_72', '10km_622_44', '10km_622_45', '10km_622_46', '10km_622_47', '10km_622_48', '10km_622_49', '10km_622_50', '10km_622_51', '10km_622_52', '10km_622_53', '10km_622_54', '10km_622_55', '10km_622_56', '10km_622_57', '10km_622_58', '10km_622_59', '10km_622_60', '10km_622_69', '10km_622_70', '10km_622_71', '10km_623_44', '10km_623_45', '10km_623_46', '10km_623_47', '10km_623_48', '10km_623_49', '10km_623_50', '10km_623_51', '10km_623_52', '10km_623_53', '10km_623_54', '10km_623_55', '10km_623_56', '10km_623_57', '10km_623_58', '10km_623_59', '10km_623_60', '10km_623_61', '10km_624_44', '10km_624_45', '10km_624_46', '10km_624_47', '10km_624_48', '10km_624_49', '10km_624_50', '10km_624_51', '10km_624_52', '10km_624_53', '10km_624_54', '10km_624_55', '10km_624_56', '10km_624_57', '10km_624_58', '10km_624_59', '10km_624_60', '10km_624_61', '10km_625_44', '10km_625_45', '10km_625_46', '10km_625_47', '10km_625_48', '10km_625_49', '10km_625_50', '10km_625_51', '10km_625_52', '10km_625_53', '10km_625_54', '10km_625_55', '10km_625_56', '10km_625_57', '10km_625_58', '10km_625_59', '10km_625_60', '10km_625_61', '10km_626_44', '10km_626_45', '10km_626_46', '10km_626_47', '10km_626_48', '10km_626_49', '10km_626_50', '10km_626_51', '10km_626_52', '10km_626_53', '10km_626_54', '10km_626_55', '10km_626_56', '10km_626_57', '10km_626_58', '10km_626_59', '10km_626_60', '10km_626_61', '10km_627_44', '10km_627_45', '10km_627_46', '10km_627_47', '10km_627_48', '10km_627_49', '10km_627_50', '10km_627_51', '10km_627_52', '10km_627_53', '10km_627_54', '10km_627_55', '10km_627_56', '10km_627_57', '10km_627_58', '10km_628_45', '10km_628_46', '10km_628_47', '10km_628_48', '10km_628_49', '10km_628_50', '10km_628_51', '10km_628_52', '10km_628_53', '10km_628_54', '10km_628_55', '10km_628_56', '10km_628_57', '10km_628_58', '10km_628_65', '10km_628_66', '10km_629_45', '10km_629_46', '10km_629_47', '10km_629_48', '10km_629_49', '10km_629_50', '10km_629_51', '10km_629_52', '10km_629_53', '10km_629_54', '10km_629_55', '10km_629_56', '10km_629_57', '10km_629_66', '10km_630_45', '10km_630_46', '10km_630_47', '10km_630_48', '10km_630_49', '10km_630_50', '10km_630_51', '10km_630_52', '10km_630_53', '10km_630_54', '10km_630_55', '10km_630_56', '10km_630_57', '10km_631_45', '10km_631_46', '10km_631_47', '10km_631_48', '10km_631_49', '10km_631_50', '10km_631_51', '10km_631_52', '10km_631_53', '10km_631_54', '10km_631_55', '10km_631_56', '10km_631_57', '10km_631_58', '10km_632_46', '10km_632_47', '10km_632_48', '10km_632_49', '10km_632_50', '10km_632_51', '10km_632_52', '10km_632_53', '10km_632_54', '10km_632_55', '10km_632_56', '10km_632_57', '10km_632_58', '10km_633_49', '10km_633_50', '10km_633_51', '10km_633_52', '10km_633_53', '10km_633_54', '10km_633_55', '10km_633_56', '10km_633_57', '10km_633_58', '10km_634_53', '10km_634_54', '10km_634_55', '10km_634_56', '10km_634_57', '10km_634_58', '10km_634_59', '10km_634_61', '10km_634_62', '10km_635_54', '10km_635_55', '10km_635_56', '10km_635_57', '10km_635_58', '10km_635_59', '10km_635_61', '10km_635_62', '10km_636_54', '10km_636_55', '10km_636_56', '10km_636_57', '10km_636_58', '10km_636_59', '10km_637_55', '10km_637_56', '10km_637_57', '10km_637_58', '10km_637_59', '10km_638_55', '10km_638_56', '10km_638_57', '10km_638_58', '10km_639_58', '10km_639_59'] grid20 = ['20km_604_64', '20km_604_66', '20km_604_68', '20km_606_50', '20km_606_52', '20km_606_54', '20km_606_58', '20km_606_60', '20km_606_62', '20km_606_64', '20km_606_66', '20km_606_68', '20km_608_46', '20km_608_48', '20km_608_50', '20km_608_52', '20km_608_54', '20km_608_56', '20km_608_58', '20km_608_60', '20km_608_62', '20km_608_64', '20km_608_66', '20km_608_68', '20km_608_70', '20km_608_72', '20km_610_46', '20km_610_48', '20km_610_50', '20km_610_52', '20km_610_54', '20km_610_56', '20km_610_58', '20km_610_60', '20km_610_62', '20km_610_64', '20km_610_66', '20km_610_68', '20km_610_70', '20km_610_72', '20km_611_86', '20km_611_88', '20km_612_46', '20km_612_48', '20km_612_50', '20km_612_52', '20km_612_54', '20km_612_56', '20km_612_58', '20km_612_60', '20km_612_62', '20km_612_64', '20km_612_66', '20km_612_68', '20km_612_70', '20km_613_86', '20km_613_88', '20km_614_44', '20km_614_46', '20km_614_48', '20km_614_50', '20km_614_52', '20km_614_54', '20km_614_56', '20km_614_58', '20km_614_60', '20km_614_62', '20km_614_64', '20km_614_66', '20km_614_68', '20km_614_70', '20km_616_44', '20km_616_46', '20km_616_48', '20km_616_50', '20km_616_52', '20km_616_54', '20km_616_56', '20km_616_58', '20km_616_60', '20km_616_62', '20km_616_64', '20km_616_66', '20km_616_68', '20km_616_70', '20km_616_72', '20km_618_44', '20km_618_46', '20km_618_48', '20km_618_50', '20km_618_52', '20km_618_54', '20km_618_56', '20km_618_58', '20km_618_60', '20km_618_62', '20km_618_64', '20km_618_66', '20km_618_68', '20km_618_70', '20km_618_72', '20km_620_44', '20km_620_46', '20km_620_48', '20km_620_50', '20km_620_52', '20km_620_54', '20km_620_56', '20km_620_58', '20km_620_64', '20km_620_66', '20km_620_68', '20km_620_70', '20km_620_72', '20km_622_44', '20km_622_46', '20km_622_48', '20km_622_50', '20km_622_52', '20km_622_54', '20km_622_56', '20km_622_58', '20km_622_60', '20km_622_68', '20km_622_70', '20km_624_44', '20km_624_46', '20km_624_48', '20km_624_50', '20km_624_52', '20km_624_54', '20km_624_56', '20km_624_58', '20km_624_60', '20km_626_44', '20km_626_46', '20km_626_48', '20km_626_50', '20km_626_52', '20km_626_54', '20km_626_56', '20km_626_58', '20km_626_60', '20km_628_44', '20km_628_46', '20km_628_48', '20km_628_50', '20km_628_52', '20km_628_54', '20km_628_56', '20km_628_58', '20km_628_65', '20km_630_44', '20km_630_46', '20km_630_48', '20km_630_50', '20km_630_52', '20km_630_54', '20km_630_56', '20km_630_58', '20km_632_46', '20km_632_48', '20km_632_50', '20km_632_52', '20km_632_54', '20km_632_56', '20km_632_58', '20km_634_52', '20km_634_54', '20km_634_56', '20km_634_58', '20km_634_61', '20km_636_54', '20km_636_56', '20km_636_58', '20km_638_54', '20km_638_56', '20km_638_58'] - para_grid = ['acc_heating_degree_days_17', 'acc_precip', 'bright_sunshine', @@ -41,902 +40,6 @@ 'temp_soil_10', 'temp_soil_30', 'vapour_pressure_deficit_mean'] - -grid_para = ['acc_heating_degree_days_17', - 'acc_precip', - 'bright_sunshine', - 'drought_index', - 'leaf_moisture', - 'max_precip_30m', - 'max_temp_w_date', - 'max_wind_speed_10min', - 'max_wind_speed_3sec', - 'mean_cloud_cover', - 'mean_daily_max_temp', - 'mean_daily_min_temp', - 'mean_pressure', - 'mean_radiation', - 'mean_relative_hum', - 'mean_temp', - 'mean_wind_dir', - 'mean_wind_speed', - 'min_temp', - 'no_cold_days', - 'no_days_acc_precip_01', - 'no_days_acc_precip_1', - 'no_days_acc_precip_10', - 'no_frost_days', - 'no_ice_days', - 'no_summer_days', - 'no_tropical_nights', - 'pot_evaporation_makkink', - 'pot_evaporation_penman', - 'snow_depth', - 'temp_grass', - 'temp_soil_10', - 'temp_soil_30', - 'vapour_pressure_deficit_mean'] - -cliamte_para_stat = ['acc_heating_degree_days_17', - 'acc_heating_degree_days_19', - 'acc_precip', - 'bright_sunshine', - 'leaf_moisture', - 'max_precip_30m', - 'max_pressure', - 'max_relative_hum', - 'max_temp_w_date', - 'max_wind_speed_10min', - 'max_wind_speed_3sec', - 'mean_cloud_cover', - 'mean_pressure', - 'mean_radiation', - 'mean_relative_hum', - 'mean_temp', - 'mean_wind_dir', - 'mean_wind_dir_min0', - 'mean_wind_speed', - 'min_pressure', - 'min_relative_hum', - 'min_temp', - 'min_temperature_12h', - 'no_days_acc_precip_01', - 'no_ice_days', - 'snow_cover', - 'snow_depth', - 'temp_grass', - 'temp_soil_10', - 'temp_soil_30', - 'vapour_pressure_deficit_mean'] -munic_dict_num = {0: '0101', - 1: '0147', - 2: '0151', - 3: '0153', - 4: '0155', - 5: '0157', - 6: '0159', - 7: '0161', - 8: '0163', - 9: '0165', - 10: '0167', - 11: '0169', - 12: '0173', - 13: '0175', - 14: '0183', - 15: '0185', - 16: '0187', - 17: '0190', - 18: '0201', - 19: '0210', - 20: '0217', - 21: '0219', - 22: '0223', - 23: '0230', - 24: '0240', - 25: '0250', - 26: '0253', - 27: '0259', - 28: '0260', - 29: '0265', - 30: '0269', - 31: '0270', - 32: '0306', - 33: '0316', - 34: '0320', - 35: '0326', - 36: '0329', - 37: '0330', - 38: '0336', - 39: '0340', - 40: '0350', - 41: '0360', - 42: '0370', - 43: '0376', - 44: '0390', - 45: '0400', - 46: '0410', - 47: '0420', - 48: '0430', - 49: '0440', - 50: '0450', - 51: '0461', - 52: '0479', - 53: '0480', - 54: '0482', - 55: '0492', - 56: '0510', - 57: '0530', - 58: '0540', - 59: '0550', - 60: '0561', - 61: '0563', - 62: '0573', - 63: '0575', - 64: '0580', - 65: '0607', - 66: '0615', - 67: '0621', - 68: '0630', - 69: '0657', - 70: '0661', - 71: '0665', - 72: '0671', - 73: '0706', - 74: '0707', - 75: '0710', - 76: '0727', - 77: '0730', - 78: '0740', - 79: '0741', - 80: '0746', - 81: '0751', - 82: '0756', - 83: '0760', - 84: '0766', - 85: '0773', - 86: '0779', - 87: '0787', - 88: '0791', - 89: '0810', - 90: '0813', - 91: '0820', - 92: '0825', - 93: '0840', - 94: '0846', - 95: '0849', - 96: '0851', - 97: '0860'} - -grid10_id = ['10km_605_66', - '10km_605_68', - '10km_606_60', - '10km_606_61', - '10km_606_63', - '10km_606_64', - '10km_606_65', - '10km_606_66', - '10km_606_67', - '10km_606_68', - '10km_606_69', - '10km_607_52', - '10km_607_54', - '10km_607_59', - '10km_607_60', - '10km_607_62', - '10km_607_64', - '10km_607_65', - '10km_607_66', - '10km_607_67', - '10km_607_68', - '10km_607_69', - '10km_608_47', - '10km_608_48', - '10km_608_49', - '10km_608_50', - '10km_608_51', - '10km_608_52', - '10km_608_54', - '10km_608_55', - '10km_608_58', - '10km_608_59', - '10km_608_60', - '10km_608_61', - '10km_608_62', - '10km_608_63', - '10km_608_64', - '10km_608_65', - '10km_608_66', - '10km_608_67', - '10km_608_69', - '10km_608_70', - '10km_609_47', - '10km_609_48', - '10km_609_49', - '10km_609_52', - '10km_609_53', - '10km_609_54', - '10km_609_55', - '10km_609_57', - '10km_609_58', - '10km_609_61', - '10km_609_62', - '10km_609_64', - '10km_609_65', - '10km_609_67', - '10km_609_69', - '10km_609_70', - '10km_609_71', - '10km_610_47', - '10km_610_49', - '10km_610_50', - '10km_610_52', - '10km_610_53', - '10km_610_55', - '10km_610_56', - '10km_610_57', - '10km_610_58', - '10km_610_59', - '10km_610_60', - '10km_610_61', - '10km_610_62', - '10km_610_65', - '10km_610_66', - '10km_610_67', - '10km_610_68', - '10km_610_69', - '10km_610_71', - '10km_610_72', - '10km_611_46', - '10km_611_47', - '10km_611_48', - '10km_611_49', - '10km_611_50', - '10km_611_51', - '10km_611_52', - '10km_611_53', - '10km_611_54', - '10km_611_56', - '10km_611_57', - '10km_611_58', - '10km_611_59', - '10km_611_60', - '10km_611_61', - '10km_611_62', - '10km_611_63', - '10km_611_65', - '10km_611_66', - '10km_611_67', - '10km_611_68', - '10km_611_69', - '10km_611_70', - '10km_611_86', - '10km_611_87', - '10km_611_88', - '10km_611_89', - '10km_612_47', - '10km_612_49', - '10km_612_51', - '10km_612_52', - '10km_612_53', - '10km_612_56', - '10km_612_57', - '10km_612_58', - '10km_612_61', - '10km_612_64', - '10km_612_65', - '10km_612_66', - '10km_612_67', - '10km_612_68', - '10km_612_69', - '10km_612_71', - '10km_612_86', - '10km_612_88', - '10km_613_46', - '10km_613_47', - '10km_613_48', - '10km_613_49', - '10km_613_51', - '10km_613_52', - '10km_613_53', - '10km_613_55', - '10km_613_57', - '10km_613_58', - '10km_613_59', - '10km_613_60', - '10km_613_63', - '10km_613_64', - '10km_613_65', - '10km_613_66', - '10km_613_68', - '10km_613_69', - '10km_613_70', - '10km_613_71', - '10km_613_87', - '10km_613_88', - '10km_614_46', - '10km_614_47', - '10km_614_48', - '10km_614_49', - '10km_614_50', - '10km_614_52', - '10km_614_53', - '10km_614_55', - '10km_614_56', - '10km_614_57', - '10km_614_58', - '10km_614_59', - '10km_614_60', - '10km_614_61', - '10km_614_63', - '10km_614_64', - '10km_614_67', - '10km_614_68', - '10km_614_69', - '10km_614_70', - '10km_614_86', - '10km_614_89', - '10km_615_44', - '10km_615_45', - '10km_615_46', - '10km_615_47', - '10km_615_48', - '10km_615_49', - '10km_615_51', - '10km_615_52', - '10km_615_53', - '10km_615_54', - '10km_615_55', - '10km_615_56', - '10km_615_57', - '10km_615_58', - '10km_615_59', - '10km_615_61', - '10km_615_63', - '10km_615_65', - '10km_615_66', - '10km_615_67', - '10km_615_68', - '10km_615_69', - '10km_615_70', - '10km_616_45', - '10km_616_46', - '10km_616_47', - '10km_616_48', - '10km_616_49', - '10km_616_50', - '10km_616_52', - '10km_616_53', - '10km_616_54', - '10km_616_55', - '10km_616_57', - '10km_616_58', - '10km_616_63', - '10km_616_69', - '10km_616_70', - '10km_616_72', - '10km_616_73', - '10km_617_44', - '10km_617_45', - '10km_617_46', - '10km_617_47', - '10km_617_48', - '10km_617_49', - '10km_617_50', - '10km_617_51', - '10km_617_52', - '10km_617_53', - '10km_617_54', - '10km_617_55', - '10km_617_56', - '10km_617_58', - '10km_617_62', - '10km_617_63', - '10km_617_64', - '10km_617_65', - '10km_617_66', - '10km_617_67', - '10km_617_68', - '10km_617_69', - '10km_617_72', - '10km_617_73', - '10km_618_44', - '10km_618_45', - '10km_618_46', - '10km_618_47', - '10km_618_49', - '10km_618_50', - '10km_618_51', - '10km_618_52', - '10km_618_54', - '10km_618_55', - '10km_618_56', - '10km_618_57', - '10km_618_58', - '10km_618_64', - '10km_618_65', - '10km_618_66', - '10km_618_67', - '10km_618_68', - '10km_618_69', - '10km_618_71', - '10km_618_72', - '10km_619_45', - '10km_619_46', - '10km_619_47', - '10km_619_48', - '10km_619_49', - '10km_619_50', - '10km_619_52', - '10km_619_53', - '10km_619_55', - '10km_619_56', - '10km_619_57', - '10km_619_59', - '10km_619_60', - '10km_619_63', - '10km_619_64', - '10km_619_65', - '10km_619_66', - '10km_619_67', - '10km_619_68', - '10km_619_69', - '10km_619_70', - '10km_619_71', - '10km_620_44', - '10km_620_45', - '10km_620_46', - '10km_620_47', - '10km_620_48', - '10km_620_49', - '10km_620_50', - '10km_620_51', - '10km_620_53', - '10km_620_54', - '10km_620_56', - '10km_620_57', - '10km_620_58', - '10km_620_59', - '10km_620_64', - '10km_620_65', - '10km_620_66', - '10km_620_68', - '10km_620_69', - '10km_620_70', - '10km_620_71', - '10km_621_44', - '10km_621_45', - '10km_621_46', - '10km_621_47', - '10km_621_48', - '10km_621_50', - '10km_621_51', - '10km_621_52', - '10km_621_53', - '10km_621_55', - '10km_621_56', - '10km_621_57', - '10km_621_59', - '10km_621_68', - '10km_621_69', - '10km_621_70', - '10km_621_71', - '10km_621_72', - '10km_622_44', - '10km_622_45', - '10km_622_47', - '10km_622_48', - '10km_622_49', - '10km_622_50', - '10km_622_51', - '10km_622_52', - '10km_622_53', - '10km_622_55', - '10km_622_56', - '10km_622_57', - '10km_622_58', - '10km_622_59', - '10km_622_60', - '10km_622_69', - '10km_622_70', - '10km_622_71', - '10km_623_44', - '10km_623_46', - '10km_623_47', - '10km_623_48', - '10km_623_49', - '10km_623_50', - '10km_623_51', - '10km_623_52', - '10km_623_53', - '10km_623_54', - '10km_623_55', - '10km_623_56', - '10km_623_57', - '10km_623_60', - '10km_623_61', - '10km_624_44', - '10km_624_45', - '10km_624_46', - '10km_624_47', - '10km_624_48', - '10km_624_50', - '10km_624_51', - '10km_624_52', - '10km_624_53', - '10km_624_54', - '10km_624_55', - '10km_624_56', - '10km_624_57', - '10km_624_59', - '10km_624_60', - '10km_624_61', - '10km_625_44', - '10km_625_45', - '10km_625_47', - '10km_625_48', - '10km_625_49', - '10km_625_51', - '10km_625_52', - '10km_625_53', - '10km_625_54', - '10km_625_55', - '10km_625_56', - '10km_625_57', - '10km_625_58', - '10km_625_59', - '10km_625_60', - '10km_625_61', - '10km_626_44', - '10km_626_45', - '10km_626_46', - '10km_626_48', - '10km_626_49', - '10km_626_51', - '10km_626_52', - '10km_626_53', - '10km_626_54', - '10km_626_55', - '10km_626_56', - '10km_626_57', - '10km_626_58', - '10km_626_59', - '10km_626_60', - '10km_626_61', - '10km_627_44', - '10km_627_46', - '10km_627_47', - '10km_627_48', - '10km_627_49', - '10km_627_51', - '10km_627_52', - '10km_627_53', - '10km_627_55', - '10km_627_56', - '10km_627_57', - '10km_627_58', - '10km_628_45', - '10km_628_46', - '10km_628_48', - '10km_628_49', - '10km_628_50', - '10km_628_51', - '10km_628_53', - '10km_628_54', - '10km_628_57', - '10km_628_58', - '10km_628_65', - '10km_628_66', - '10km_629_47', - '10km_629_48', - '10km_629_49', - '10km_629_51', - '10km_629_53', - '10km_629_55', - '10km_629_56', - '10km_629_57', - '10km_629_66', - '10km_630_45', - '10km_630_46', - '10km_630_48', - '10km_630_50', - '10km_630_52', - '10km_630_53', - '10km_630_54', - '10km_630_57', - '10km_631_45', - '10km_631_47', - '10km_631_48', - '10km_631_49', - '10km_631_51', - '10km_631_52', - '10km_631_55', - '10km_631_56', - '10km_631_57', - '10km_632_46', - '10km_632_48', - '10km_632_50', - '10km_632_51', - '10km_632_52', - '10km_632_53', - '10km_632_55', - '10km_632_56', - '10km_632_57', - '10km_632_58', - '10km_633_50', - '10km_633_52', - '10km_633_55', - '10km_633_56', - '10km_633_57', - '10km_633_58', - '10km_634_53', - '10km_634_54', - '10km_634_57', - '10km_634_58', - '10km_634_59', - '10km_634_61', - '10km_634_62', - '10km_635_54', - '10km_635_55', - '10km_635_56', - '10km_635_57', - '10km_635_58', - '10km_635_59', - '10km_635_61', - '10km_635_62', - '10km_636_54', - '10km_636_56', - '10km_636_57', - '10km_636_58', - '10km_636_59', - '10km_637_57', - '10km_637_58', - '10km_637_59', - '10km_638_56', - '10km_638_57', - '10km_638_58', - '10km_639_58', - '10km_639_59'] -grid20_id = ['20km_604_64', - '20km_604_66', - '20km_604_68', - '20km_606_50', - '20km_606_52', - '20km_606_54', - '20km_606_58', - '20km_606_60', - '20km_606_62', - '20km_606_64', - '20km_606_66', - '20km_606_68', - '20km_608_46', - '20km_608_48', - '20km_608_50', - '20km_608_52', - '20km_608_54', - '20km_608_56', - '20km_608_58', - '20km_608_60', - '20km_608_62', - '20km_608_64', - '20km_608_66', - '20km_608_68', - '20km_608_70', - '20km_608_72', - '20km_610_46', - '20km_610_48', - '20km_610_50', - '20km_610_52', - '20km_610_54', - '20km_610_56', - '20km_610_58', - '20km_610_60', - '20km_610_62', - '20km_610_64', - '20km_610_66', - '20km_610_68', - '20km_610_70', - '20km_610_72', - '20km_611_86', - '20km_611_88', - '20km_612_46', - '20km_612_48', - '20km_612_50', - '20km_612_52', - '20km_612_54', - '20km_612_56', - '20km_612_58', - '20km_612_60', - '20km_612_62', - '20km_612_64', - '20km_612_66', - '20km_612_68', - '20km_612_70', - '20km_613_86', - '20km_613_88', - '20km_614_46', - '20km_614_48', - '20km_614_50', - '20km_614_52', - '20km_614_54', - '20km_614_56', - '20km_614_58', - '20km_614_60', - '20km_614_62', - '20km_614_64', - '20km_614_66', - '20km_614_68', - '20km_614_70', - '20km_616_44', - '20km_616_46', - '20km_616_48', - '20km_616_50', - '20km_616_52', - '20km_616_54', - '20km_616_56', - '20km_616_58', - '20km_616_60', - '20km_616_62', - '20km_616_64', - '20km_616_66', - '20km_616_68', - '20km_616_70', - '20km_616_72', - '20km_618_44', - '20km_618_46', - '20km_618_48', - '20km_618_50', - '20km_618_52', - '20km_618_54', - '20km_618_56', - '20km_618_58', - '20km_618_60', - '20km_618_62', - '20km_618_64', - '20km_618_66', - '20km_618_68', - '20km_618_70', - '20km_618_72', - '20km_620_44', - '20km_620_46', - '20km_620_48', - '20km_620_50', - '20km_620_52', - '20km_620_54', - '20km_620_56', - '20km_620_58', - '20km_620_64', - '20km_620_66', - '20km_620_68', - '20km_620_70', - '20km_620_72', - '20km_622_44', - '20km_622_46', - '20km_622_48', - '20km_622_50', - '20km_622_52', - '20km_622_54', - '20km_622_56', - '20km_622_58', - '20km_622_60', - '20km_622_68', - '20km_622_70', - '20km_624_46', - '20km_624_48', - '20km_624_50', - '20km_624_52', - '20km_624_54', - '20km_624_56', - '20km_624_58', - '20km_624_60', - '20km_626_44', - '20km_626_46', - '20km_626_48', - '20km_626_50', - '20km_626_52', - '20km_626_54', - '20km_626_56', - '20km_626_58', - '20km_626_60', - '20km_628_44', - '20km_628_46', - '20km_628_48', - '20km_628_50', - '20km_628_52', - '20km_628_54', - '20km_628_56', - '20km_628_58', - '20km_628_65', - '20km_630_44', - '20km_630_46', - '20km_630_48', - '20km_630_50', - '20km_630_52', - '20km_630_54', - '20km_630_56', - '20km_630_58', - '20km_632_46', - '20km_632_48', - '20km_632_50', - '20km_632_52', - '20km_632_54', - '20km_632_56', - '20km_632_58', - '20km_634_52', - '20km_634_54', - '20km_634_56', - '20km_634_58', - '20km_634_61', - '20km_636_54', - '20km_636_56', - '20km_636_58', - '20km_638_54', - '20km_638_56', - '20km_638_58'] -grid_para = ['acc_heating_degree_days_17', - 'acc_precip', - 'bright_sunshine', - 'drought_index', - 'leaf_moisture', - 'max_precip_30m', - 'max_temp_w_date', - 'max_wind_speed_10min', - 'max_wind_speed_3sec', - 'mean_cloud_cover', - 'mean_daily_max_temp', - 'mean_daily_min_temp', - 'mean_pressure', - 'mean_radiation', - 'mean_relative_hum', - 'mean_temp', - 'mean_wind_dir', - 'mean_wind_speed', - 'min_temp', - 'no_cold_days', - 'no_days_acc_precip_01', - 'no_days_acc_precip_1', - 'no_days_acc_precip_10', - 'no_frost_days', - 'no_ice_days', - 'no_summer_days', - 'no_tropical_nights', - 'pot_evaporation_makkink', - 'pot_evaporation_penman', - 'snow_depth', - 'temp_grass', - 'temp_soil_10', - 'temp_soil_30', - 'vapour_pressure_deficit_mean'] -cliamte_para_stat = ['acc_heating_degree_days_17', - 'acc_heating_degree_days_19', - 'acc_precip', - 'bright_sunshine', - 'leaf_moisture', - 'max_precip_30m', - 'max_pressure', - 'max_relative_hum', - 'max_temp_w_date', - 'max_wind_speed_10min', - 'max_wind_speed_3sec', - 'mean_cloud_cover', - 'mean_pressure', - 'mean_radiation', - 'mean_relative_hum', - 'mean_temp', - 'mean_wind_dir', - 'mean_wind_dir_min0', - 'mean_wind_speed', - 'min_pressure', - 'min_relative_hum', - 'min_temp', - 'min_temperature_12h', - 'no_days_acc_precip_01', - 'no_ice_days', - 'snow_cover', - 'snow_depth', - 'temp_grass', - 'temp_soil_10', - 'temp_soil_30', - 'vapour_pressure_deficit_mean'] munic = ['0101', '0147', '0151', @@ -1035,3 +138,4 @@ '0849', '0851', '0860'] +munic_id_name = ['Aabenraa 0580', 'Aalborg 0851', 'Aarhus 0751', 'Albertslund 0165', 'Allerød 0201', 'Assens 0420', 'Ballerup 0151', 'Billund 0530', 'Bornholm 0400', 'Brøndby 0153', 'Brønderslev 0810', 'Dragør 0155', 'Egedal 0240', 'Esbjerg 0561', 'Faaborg-Midtfyn 0430', 'Fanø 0563', 'Favrskov 0710', 'Faxe 0320', 'Fredensborg 0210', 'Fredericia 0607', 'Frederiksberg 0147', 'Frederikshavn 0813', 'Frederikssund 0250', 'Furesø 0190', 'Gentofte 0157', 'Gladsaxe 0159', 'Glostrup 0161', 'Greve 0253', 'Gribskov 0270', 'Guldborgsund 0376', 'Haderslev 0510', 'Halsnæs 0260', 'Hedensted 0766', 'Helsingør 0217', 'Herlev 0163', 'Herning 0657', 'Hillerød 0219', 'Hjørring 0860', 'Holbæk 0316', 'Holstebro 0661', 'Horsens 0615', 'Hvidovre 0167', 'Høje-Taastrup 0169', 'Hørsholm 0223', 'Ikast-Brande 0756', 'Ishøj 0183', 'Jammerbugt 0849', 'Kalundborg 0326', 'Kerteminde 0440', 'Kolding 0621', 'København 0101', 'Køge 0259', 'Langeland 0482', 'Lejre 0350', 'Lemvig 0665', 'Lolland 0360', 'Lyngby-Taarbæk 0173', 'Læsø 0825', 'Mariagerfjord 0846', 'Middelfart 0410', 'Morsø 0773', 'Norddjurs 0707', 'Nordfyns 0480', 'Nyborg 0450', 'Næstved 0370', 'Odder 0727', 'Odense 0461', 'Odsherred 0306', 'Randers 0730', 'Rebild 0840', 'Ringkøbing-Skjern 0760', 'Ringsted 0329', 'Roskilde 0265', 'Rudersdal 0230', 'Rødovre 0175', 'Samsø 0741', 'Silkeborg 0740', 'Skanderborg 0746', 'Skive 0779', 'Slagelse 0330', 'Solrød 0269', 'Sorø 0340', 'Stevns 0336', 'Struer 0671', 'Svendborg 0479', 'Syddjurs 0706', 'Sønderborg 0540', 'Thisted 0787', 'Tårnby 0185', 'Tønder 0550', 'Vallensbæk 0187', 'Varde 0573', 'Vejen 0575', 'Vejle 0630', 'Vesthimmerlands 0820', 'Viborg 0791', 'Vordingborg 0390', 'Ærø 0492'] diff --git a/settings/settings.ui b/settings/settings.ui index 15ddd2a..9cb47db 100644 --- a/settings/settings.ui +++ b/settings/settings.ui @@ -44,9 +44,9 @@ 0 - 0 - 511 - 334 + -95 + 491 + 480 @@ -155,13 +155,25 @@ - + API Key forecastData + + + + + + + + + + + API Key forecastEDRData + - + diff --git a/settings/settings_manager.py b/settings/settings_manager.py index 41ba47e..0640024 100644 --- a/settings/settings_manager.py +++ b/settings/settings_manager.py @@ -7,7 +7,7 @@ class DMISettingKeys(Enum): """ - Holds the keys for this plugin settings retrievable by the DMISettingsManager. Note that these should match the + Holds the keys for this pluging settings retrievable by the DMISettingsManaer. Note that these should match the object names of the settings input widgets in settings.ui file. """ METOBS_API_KEY = 'DMI_apiKey_metObs' @@ -15,7 +15,8 @@ class DMISettingKeys(Enum): CLIMATEDATA_API_KEY = 'DMI_apiKey_climateData' LIGHTNINGDATA_API_KEY = 'DMI_apiKey_lightningData' RADARDATA_API_KEY = 'DMI_apiKey_radarData' - FORECASTDATA_API_KEY = 'DMI_apiKey_forecastData' + FORECASTDATA_GRIB_API_KEY = 'DMI_apiKey_forecastData_GRIB' + FORECASTDATA_EDR_API_KEY = 'DMI_apiKey_forecastEDRData' def get_api_name(self) -> str: if self is DMISettingKeys.METOBS_API_KEY: @@ -28,8 +29,10 @@ def get_api_name(self) -> str: return 'Lightning Data' if self is DMISettingKeys.RADARDATA_API_KEY: return 'Radar Data' - if self is DMISettingKeys.RADARDATA_API_KEY: - return 'Forecast Data' + if self is DMISettingKeys.FORECASTDATA_GRIB_API_KEY: + return 'Forecast GRIB Data' + if self is DMISettingKeys.FORECASTDATA_EDR_API_KEY: + return 'ForecastEDR Data' class DMISettingsManager(SettingManager, QObject): @@ -43,7 +46,8 @@ def __init__(self): self.add_setting(String(DMISettingKeys.CLIMATEDATA_API_KEY.value, Scope.Global, '')) self.add_setting(String(DMISettingKeys.LIGHTNINGDATA_API_KEY.value, Scope.Global, '')) self.add_setting(String(DMISettingKeys.RADARDATA_API_KEY.value, Scope.Global, '')) - self.add_setting(String(DMISettingKeys.FORECASTDATA_API_KEY.value, Scope.Global, '')) + self.add_setting(String(DMISettingKeys.FORECASTDATA_GRIB_API_KEY.value, Scope.Global, '')) + self.add_setting(String(DMISettingKeys.FORECASTDATA_EDR_API_KEY.value, Scope.Global, '')) def emit_updated(self): self.settings_updated.emit()