From 6ddb800c490d72bf6353aef5ab6be0ad269d002e Mon Sep 17 00:00:00 2001
From: Emmanuel Heriberto Oceguera Conchas <e.oceguera@gmx.de>
Date: Mon, 14 Nov 2022 10:49:15 +0100
Subject: [PATCH] name changed

---
 EBVCubeVisualizer.py              | 181 +++++++++++++
 EBVCubeVisualizer.ui              | 429 ++++++++++++++++++++++++++++++
 EBVCubeVisualizer_funtionality.py | 390 +++++++++++++++++++++++++++
 __init__.py                       |   4 +-
 metadata.txt                      |   2 +-
 styles/raster_style.qml           |  91 +++++++
 6 files changed, 1094 insertions(+), 3 deletions(-)
 create mode 100644 EBVCubeVisualizer.py
 create mode 100644 EBVCubeVisualizer.ui
 create mode 100644 EBVCubeVisualizer_funtionality.py
 create mode 100644 styles/raster_style.qml

diff --git a/EBVCubeVisualizer.py b/EBVCubeVisualizer.py
new file mode 100644
index 0000000..922f4f7
--- /dev/null
+++ b/EBVCubeVisualizer.py
@@ -0,0 +1,181 @@
+'''
+/****************************************************************************************
+* 
+* 
+* 
+* 
+* 
+****************************************************************************************/
+
+/****************************************************************************************
+* The program is free software; you can redistribute it and/or modify                   
+* it under the terms of the GNU General Public License as published by                  
+* the Free Software Foundation; either version 2 of the License, or                              
+* at your option) any later version.                                                     
+* 
+* The script is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+* See the GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License along with this program. 
+* If not, see http://www.gnu.org/licenses/.
+****************************************************************************************/
+'''
+#we import the important functions from the pyQt5 library
+
+from PyQt5.QtCore import *  
+from PyQt5.QtGui import *  
+from PyQt5.QtWidgets import *  
+#import everthing from the netCDF_visualization_funtionality.py file
+from .EBVCubeVisualizer_funtionality import *
+#we write a class, Plugins is a class
+import os
+
+
+
+class EBVCubeVisualizer:
+    """This is a class for the EBVCubeVisualizer Plugin"""
+    #we set that we need the iface to build something with the class
+    def __init__(self, iface):
+        """Constructor.
+        :param iface: An interface instance that will be passed to this class
+            which provides the hook by which you can manipulate the QGIS
+            application at run time.
+        :type iface: QgsInterface
+        """
+        #our class builds netCDF_visualization Plugins
+        #self is a Plugin
+        #we set the iface as an attribute!!
+        self.iface = iface
+        #initialize locale
+        locale = QSettings().value('locale/userLocale')[0:2]
+        locale_path = os.path.join(
+            os.path.dirname(__file__),
+            'i18n',
+            'EBVCubeVisualizer_{}.qm'.format(locale))
+        if os.path.exists(locale_path):
+            self.translator = QTranslator()
+            self.translator.load(locale_path)
+            if qVersion() > '4.3.3':
+                QCoreApplication.installTranslator(self.translator)
+    
+        #decalre instance attributes
+        self.actions = []
+        self.menu = self.tr(u'&EBVCubeVisualizer')
+        #we want to add a toolbar
+        self.toolbar = self.iface.addToolBar(u'EBVCubeVisualizer')
+        self.toolbar.setObjectName(u'EBVCubeVisualizer')
+        
+        #print "** INITIALIZING netCDFVisualizer"
+
+        self.pluginIsActive = False
+        self.dockwidget = None
+    
+    def tr(self, message):
+        """Get the translation for a string using Qt translation API.
+        We implement this ourselves since we do not inherit QObject.
+        :param message: String for translation.
+        :type message: str, QString
+        :returns: Translated version of message.
+        :rtype: QString
+        """
+        return QCoreApplication.translate('EBVCubeVisualizer', message)
+        
+    def add_action(
+        self,
+        icon_path,
+        text,
+        callback,
+        enabled_flag=True,
+        add_to_menu=True,
+        add_to_toolbar=True,
+        status_tip=None,
+        whats_this=None,
+        parent=None):
+        """Add a toolbar icon to the toolbar.
+
+        :param icon_path: Path to the icon for this action. Can be a resource
+            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
+        :type icon_path: str
+
+        :param text: Text that should be shown in menu items for this action.
+        :type text: str
+
+        :param callback: Function to be called when the action is triggered.
+        :type callback: function
+
+        :param enabled_flag: A flag indicating if the action should be enabled
+            by default. Defaults to True.
+        :type enabled_flag: bool
+
+        :param add_to_menu: Flag indicating whether the action should also
+            be added to the menu. Defaults to True.
+        :type add_to_menu: bool
+
+        :param add_to_toolbar: Flag indicating whether the action should also
+            be added to the toolbar. Defaults to True.
+        :type add_to_toolbar: bool
+
+        :param status_tip: Optional text to show in a popup when mouse pointer
+            hovers over the action.
+        :type status_tip: str
+
+        :param parent: Parent widget for the new action. Defaults None.
+        :type parent: QWidget
+
+        :param whats_this: Optional text to show in the status bar when the
+            mouse pointer hovers over the action.
+
+        :returns: The action that was created. Note that the action is also
+            added to self.actions list.
+        :rtype: QAction
+        """
+        icon = QIcon(icon_path)
+        action = QAction(icon, text, parent)
+        action.triggered.connect(callback)
+        action.setEnabled(enabled_flag)
+
+        if status_tip is not None:
+            action.setStatusTip(status_tip)
+        
+        if whats_this is not None:
+            action.setWhatsThis(whats_this)
+        
+        if add_to_toolbar:
+            self.iface.addToolBarIcon(action)
+        
+        if add_to_menu:
+            self.iface.addPluginToMenu(
+                self.menu,
+                action)
+        self.actions.append(action)
+        return action
+
+    #when we click the plugin in QGIS the plugin will be loaded
+    def initGui(self):
+        """Create the menu entries and toolbar icons inside the QGIS GUI."""
+        icon_path = ':/plugins/EBVCubeVisualizer/adventure.png'
+        self.add_action(
+            icon_path,
+            text=self.tr(u'EBVCubeVisualizer'),
+            callback=self.callMask,
+            parent=self.iface.mainWindow())
+
+    #when we close the plugin in QGIS the plugin will be unloaded
+    def unload(self):
+        """Removes the plugin menu item and icon from QGIS GUI."""	
+        for action in self.actions:
+            self.iface.removePluginMenu(
+                self.tr(u'&EBVCubeVisualizer'),
+                action)
+            self.iface.removeToolBarIcon(action)
+        else :
+            self.toolbar.removeAction(action)
+           
+    #we create a function to call the mask       
+    def callMask(self):
+        #we create the mask or GUI
+        self.mask = maskAndFuntionality(self.iface)
+        #we show the mask
+        self.mask.show()
+
diff --git a/EBVCubeVisualizer.ui b/EBVCubeVisualizer.ui
new file mode 100644
index 0000000..47278a2
--- /dev/null
+++ b/EBVCubeVisualizer.ui
@@ -0,0 +1,429 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>netCDF</class>
+ <widget class="QDialog" name="netCDF">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1273</width>
+    <height>792</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>1273</width>
+    <height>0</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>16777190</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>EBVCubeVisualizer</string>
+  </property>
+  <property name="styleSheet">
+   <string notr="true">background-color: rgb(249, 255, 254);</string>
+  </property>
+  <property name="modal">
+   <bool>false</bool>
+  </property>
+  <widget class="QLabel" name="label_6">
+   <property name="geometry">
+    <rect>
+     <x>20</x>
+     <y>10</y>
+     <width>61</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="font">
+    <font>
+     <weight>75</weight>
+     <bold>true</bold>
+    </font>
+   </property>
+   <property name="text">
+    <string>Load data:</string>
+   </property>
+  </widget>
+  <widget class="QWidget" name="horizontalLayoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>40</y>
+     <width>751</width>
+     <height>25</height>
+    </rect>
+   </property>
+   <layout class="QHBoxLayout" name="horizontalLayout">
+    <item>
+     <widget class="QToolButton" name="btn_inputFile">
+      <property name="text">
+       <string>...</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QLineEdit" name="text_set"/>
+    </item>
+    <item>
+     <widget class="QPushButton" name="btn_load">
+      <property name="text">
+       <string>load</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QWidget" name="gridLayoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>90</y>
+     <width>751</width>
+     <height>651</height>
+    </rect>
+   </property>
+   <layout class="QGridLayout" name="gridLayout">
+    <item row="0" column="1">
+     <widget class="QTabWidget" name="tabWidget">
+      <property name="maximumSize">
+       <size>
+        <width>249000</width>
+        <height>16777215</height>
+       </size>
+      </property>
+      <property name="currentIndex">
+       <number>0</number>
+      </property>
+      <widget class="QWidget" name="tab">
+       <attribute name="title">
+        <string>Datasets</string>
+       </attribute>
+       <layout class="QFormLayout" name="formLayout">
+        <item row="0" column="1">
+         <widget class="QTreeWidget" name="tree_data">
+          <property name="font">
+           <font>
+            <weight>50</weight>
+            <bold>false</bold>
+           </font>
+          </property>
+          <property name="styleSheet">
+           <string notr="true">alternate-background-color: rgb(205, 233, 236);</string>
+          </property>
+          <property name="horizontalScrollBarPolicy">
+           <enum>Qt::ScrollBarAsNeeded</enum>
+          </property>
+          <property name="sizeAdjustPolicy">
+           <enum>QAbstractScrollArea::AdjustToContents</enum>
+          </property>
+          <property name="autoScrollMargin">
+           <number>50</number>
+          </property>
+          <property name="alternatingRowColors">
+           <bool>true</bool>
+          </property>
+          <property name="horizontalScrollMode">
+           <enum>QAbstractItemView::ScrollPerItem</enum>
+          </property>
+          <property name="indentation">
+           <number>20</number>
+          </property>
+          <attribute name="headerCascadingSectionResizes">
+           <bool>true</bool>
+          </attribute>
+          <attribute name="headerMinimumSectionSize">
+           <number>206</number>
+          </attribute>
+          <attribute name="headerDefaultSectionSize">
+           <number>300</number>
+          </attribute>
+          <attribute name="headerShowSortIndicator" stdset="0">
+           <bool>true</bool>
+          </attribute>
+          <column>
+           <property name="text">
+            <string>Name</string>
+           </property>
+          </column>
+          <column>
+           <property name="text">
+            <string>Long Name</string>
+           </property>
+          </column>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QWidget" name="layoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>1010</x>
+     <y>750</y>
+     <width>231</width>
+     <height>25</height>
+    </rect>
+   </property>
+   <layout class="QHBoxLayout" name="horizontalLayout_3">
+    <item>
+     <spacer name="horizontalSpacer_2">
+      <property name="orientation">
+       <enum>Qt::Horizontal</enum>
+      </property>
+      <property name="sizeHint" stdset="0">
+       <size>
+        <width>64</width>
+        <height>20</height>
+       </size>
+      </property>
+     </spacer>
+    </item>
+    <item>
+     <widget class="QPushButton" name="btn_closePlugin">
+      <property name="text">
+       <string>Close</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QWidget" name="layoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>770</x>
+     <y>110</y>
+     <width>491</width>
+     <height>381</height>
+    </rect>
+   </property>
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <property name="sizeConstraint">
+     <enum>QLayout::SetDefaultConstraint</enum>
+    </property>
+    <item>
+     <widget class="QTextBrowser" name="text_info"/>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QWidget" name="layoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>30</x>
+     <y>750</y>
+     <width>221</width>
+     <height>25</height>
+    </rect>
+   </property>
+   <layout class="QHBoxLayout" name="horizontalLayout_2">
+    <item>
+     <widget class="QPushButton" name="btn_remove">
+      <property name="text">
+       <string>Remove all</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QPushButton" name="btn_remove_sel">
+      <property name="text">
+       <string>Remove</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <spacer name="horizontalSpacer_3">
+      <property name="orientation">
+       <enum>Qt::Horizontal</enum>
+      </property>
+      <property name="sizeHint" stdset="0">
+       <size>
+        <width>56</width>
+        <height>20</height>
+       </size>
+      </property>
+     </spacer>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QFrame" name="load_map">
+   <property name="geometry">
+    <rect>
+     <x>770</x>
+     <y>500</y>
+     <width>491</width>
+     <height>241</height>
+    </rect>
+   </property>
+   <property name="sizePolicy">
+    <sizepolicy hsizetype="Fixed" vsizetype="Ignored">
+     <horstretch>0</horstretch>
+     <verstretch>0</verstretch>
+    </sizepolicy>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">background-color: rgb(198, 225, 221);</string>
+   </property>
+   <property name="frameShape">
+    <enum>QFrame::StyledPanel</enum>
+   </property>
+   <property name="frameShadow">
+    <enum>QFrame::Raised</enum>
+   </property>
+   <widget class="QWidget" name="verticalLayoutWidget">
+    <property name="geometry">
+     <rect>
+      <x>140</x>
+      <y>210</y>
+      <width>221</width>
+      <height>25</height>
+     </rect>
+    </property>
+    <layout class="QVBoxLayout" name="verticalLayout_2">
+     <item>
+      <widget class="QPushButton" name="btn_plot">
+       <property name="styleSheet">
+        <string notr="true">selection-background-color: rgb(83, 194, 200);</string>
+       </property>
+       <property name="text">
+        <string>data display</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </widget>
+   <widget class="QWidget" name="formLayoutWidget">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>10</y>
+      <width>231</width>
+      <height>189</height>
+     </rect>
+    </property>
+    <layout class="QFormLayout" name="formLayout_2">
+     <item row="0" column="0">
+      <widget class="QLabel" name="label">
+       <property name="font">
+        <font>
+         <weight>75</weight>
+         <bold>true</bold>
+        </font>
+       </property>
+       <property name="text">
+        <string>map data</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="label_4">
+       <property name="text">
+        <string>Scenario:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="QComboBox" name="cbox_scenarios"/>
+     </item>
+     <item row="4" column="0">
+      <widget class="QLabel" name="label_5">
+       <property name="text">
+        <string>Metric:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="4" column="1">
+      <widget class="QComboBox" name="cbox_metric"/>
+     </item>
+     <item row="7" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Entity:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="7" column="1">
+      <widget class="QComboBox" name="cbox_entity"/>
+     </item>
+     <item row="8" column="0">
+      <widget class="QLabel" name="label_3">
+       <property name="text">
+        <string>Time:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="8" column="1">
+      <widget class="QComboBox" name="cbox_time"/>
+     </item>
+     <item row="5" column="1">
+      <spacer name="verticalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>40</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item row="1" column="1">
+      <spacer name="verticalSpacer">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>40</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item row="5" column="0">
+      <widget class="QLabel" name="label_7">
+       <property name="font">
+        <font>
+         <weight>75</weight>
+         <bold>true</bold>
+        </font>
+       </property>
+       <property name="text">
+        <string>         text:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="label_8">
+       <property name="font">
+        <font>
+         <weight>75</weight>
+         <bold>true</bold>
+        </font>
+       </property>
+       <property name="text">
+        <string>        text:</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </widget>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/EBVCubeVisualizer_funtionality.py b/EBVCubeVisualizer_funtionality.py
new file mode 100644
index 0000000..52b2e00
--- /dev/null
+++ b/EBVCubeVisualizer_funtionality.py
@@ -0,0 +1,390 @@
+'''
+/****************************************************************************************
+* This is a python script for visualizing netCDF files using PyQt5 and matplotlib
+* 
+* The script is based on the QGIS plugin template by Gispo
+* 
+* 
+****************************************************************************************/
+
+/****************************************************************************************
+* The program is free software; you can redistribute it and/or modify                   
+* it under the terms of the GNU General Public License as published by                  
+* the Free Software Foundation; either version 2 of the License, or                              
+* at your option) any later version.                                                     
+* 
+* The script is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+* See the GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License along with this program. 
+* If not, see http://www.gnu.org/licenses/.
+****************************************************************************************/
+'''
+#we import the impotant libraries and modules
+#always import the libraries and modules at the top of the code
+from datetime import datetime
+from json import load
+from msilib.schema import tables
+from PyQt5.QtCore import *  
+from PyQt5.QtGui import *
+from PyQt5.QtWidgets import *
+from PyQt5 import uic
+
+#we want to work with the os module
+import os
+#to import general tools from QGIS we need the qgis.core module
+from qgis.core import *
+from qgis.utils import iface
+
+#for loading the netCDF files we need the netCDF4 module
+try:
+   from pip import main as pipmain
+except ImportError:
+   from pip._internal import main as pipmain
+
+try:
+   import netCDF4 as nc
+except ImportError:
+   pipmain(['install', 'netCDF4'])
+   import netCDF4 as nc
+   from netCDF4 import Dataset
+   
+
+#we need the matplotlib module to plot the data
+import matplotlib.pyplot as plt
+#we need gdal to work with the raster data 
+from osgeo import osr, gdal, ogr
+#we ned the numpy module to work with the data
+import numpy as np
+
+
+#we create the path to the ui file
+#Path to the Ordner where the ui file is
+ncvPath = os.path.dirname(__file__) #the comand dirname gives the path to the directory where the file is
+#path to the ui file
+#dosn't matter where the ui file is located in the directory 
+uiPath = os.path.join(ncvPath, 'EBVCubeVisualizer.ui')
+
+#TWO CLASES#    
+# WIDEGT is a class for the GUI
+# BASE is a PyQt5 class to insatalize the GUI
+WIDGET, BASE = uic.loadUiType(uiPath)
+
+class maskAndFuntionality (BASE, WIDGET):
+    """Class for the mask and the funtionality of the netCDFVisualizer Plugin"""
+    def __init__(self, iface):
+        #self is GUI and mask
+        QDialog.__init__(self, iface.mainWindow())
+        self.setupUi(self)
+        #self ist our GUI
+        #the GUI is built in the running of QGIS in the current session (using the iface)
+        """ Here is the place for the Clicked Signal"""
+        self.btn_closePlugin.clicked.connect(self.closePlugin)
+        self.btn_inputFile.clicked.connect(self.importData)
+        self.btn_remove.clicked.connect(self.removePath)
+        self.btn_load.clicked.connect(self.loadNetCDF)
+        self.btn_load.clicked.connect(self.setMapData)
+        self.btn_remove_sel.clicked.connect(self.removeSelection)
+        #here we set the clicked signal for the tree widget
+        self.tree_data.itemClicked.connect(self.showInfo)
+        self.btn_plot.clicked.connect(self.displayData)
+        
+        """Here is the place for set stzlesheet"""
+        #self.btn_plot.setStyleSheet("backgrou")
+
+    def closePlugin(self):
+        """This function closes the plugin"""
+        #we close the plugin
+        self.close()
+
+    def importData(self):
+        """This function imports the netCDF file"""
+        #we get the path to the netCDF file
+        path = QFileDialog.getOpenFileName(None,"select netCDF file", filter="*.nc")[0]
+        #we set the path in the text space
+        self.text_set.setText(path)
+
+    def removePath(self):
+        """This function removes the path from the text space"""
+        self.text_set.clear()
+        self.tree_data.clear()
+        self.text_info.clear()
+        self.cbox_entity.clear()
+        self.cbox_time.clear()
+        self.cbox_scenarios.clear()
+        self.cbox_metric.clear()
+
+    def removeSelection(self):
+        """this function remove the selection in the tree widget"""
+        #if the top level item is selected we remove the Item and the children as well text_info, cbox_entity and cbox_time
+        if self.tree_data.currentItem().parent() == None:
+            self.tree_data.takeTopLevelItem(self.tree_data.indexOfTopLevelItem(self.tree_data.currentItem()))
+            self.text_info.clear()
+            self.cbox_entity.clear()
+            self.cbox_time.clear()
+            self.cbox_scenarios.clear()
+            self.cbox_metric.clear()
+        #if the child item is selected we don't remove anything
+        elif self.tree_data.currentItem() == None:
+            pass
+
+        else:
+            pass
+            
+
+    def loadNetCDF(self):
+        """This function loads the netCDF file and shows the variables, groups and the variables of the gorups in the QTreeWidget"""
+        #we get the path from the text space
+        if self.text_set.text()=="": #if the text space is empty
+            QmessageBox.warning(None, "Warning", "Please select a netCDF file") #we show a warning
+       
+        else: #if the text space is not empty
+            path = self.text_set.text() #we get the path from the text space
+            ncFile = nc.Dataset(path, 'r', format='NETCDF4')
+            ncFileName = os.path.basename(path)
+            ncFileTitle = ncFile.title
+            #convert file name and file title into a QTreeWidgetItem
+            top_level = QTreeWidgetItem([ncFileName, ncFileTitle])
+            #we get the variables of the netCDf file
+            ncFileVariablesName = list(ncFile.variables.keys())
+            ncFileGroupsName = list(ncFile.groups.keys())
+  
+            
+            #we set the top of the tree that it is the name od the file
+            self.tree_data.addTopLevelItem(top_level)
+            
+        
+            #we show the groups of the file in the QTreeWidgetite
+            for i in range(len(ncFileGroupsName)):
+                longNameGroups = ncFile.groups[ncFileGroupsName[i]].long_name
+                child = QTreeWidgetItem([ncFileGroupsName[i], longNameGroups])
+                top_level.addChild(child)
+                
+                #we get the groups of the groups
+                ncFileGroupsName2 = list(ncFile.groups[ncFileGroupsName[i]].groups.keys())
+               
+                #we show the groups of the groups in the QTreeWidgetite
+                for j in range(len(ncFileGroupsName2)):
+                    longNameGroups2 = ncFile.groups[ncFileGroupsName[i]].groups[ncFileGroupsName2[j]].long_name
+                    child2 = QTreeWidgetItem([ncFileGroupsName2[j], longNameGroups2])
+                    child.addChild(child2)
+                        
+                    #we get the variables of the groups of the groups
+                    ncFileVariablesName2 = list(ncFile.groups[ncFileGroupsName[i]].groups[ncFileGroupsName2[j]].variables.keys())
+                   
+                    #we show the variables of the groups of the groups in the QTreeWidgetite an set the lon name of the variables
+                    for k in range(len(ncFileVariablesName2)):
+                        longNameVariables2 = ncFile.groups[ncFileGroupsName[i]].groups[ncFileGroupsName2[j]].variables[ncFileVariablesName2[k]].long_name
+                        child3 = QTreeWidgetItem([ncFileVariablesName2[k], longNameVariables2])
+                        child2.addChild(child3)
+
+                #we get the variables of the groups
+                ncFileGroupsVariablesName = list(ncFile.groups[ncFileGroupsName[i]].variables.keys())
+                
+                #we show the variables of the groups in the QTreeWidgetite and set the long name of the variables
+                for j in range(len(ncFileGroupsVariablesName)):
+                    longNameVariables = ncFile.groups[ncFileGroupsName[i]].variables[ncFileGroupsVariablesName[j]].long_name
+                    child4 = QTreeWidgetItem([ncFileGroupsVariablesName[j],longNameVariables])
+                    child.addChild(child4)
+        
+            
+            #expand all the data 
+            self.tree_data.expandAll()
+            ncFile.close() #close the file
+            
+    def setMapData(self):
+        """This function sets the entities, time, scenarios and metrics in the QComboBox"""
+        #we clear the QComboBox
+        self.cbox_entity.clear()
+        self.cbox_time.clear()
+        self.cbox_scenarios.clear()
+        self.cbox_metric.clear()
+        
+        #we get the path from the text space
+        path = self.text_set.text()
+        ncFile = nc.Dataset(path, 'r', format='NETCDF4') 
+
+        groups = list(ncFile.groups.keys()) #we get the metrics (name of the groups)
+        groupsOfGroups = list(ncFile.groups[groups[0]].groups.keys()) #we get the scenarios(name of the groups of the groups)
+
+
+        #set scenario and metric in the QComboBox  
+        #if there is just groups we set the groups in the cbox_metric 
+        self.cbox_metric.addItems(groups)
+        self.cbox_scenarios.addItem("not scenarios")
+        self.cbox_scenarios.setEnabled(False)
+        
+        if len(groupsOfGroups)>0:
+            self.cbox_scenarios.setEnabled(True)
+            self.cbox_scenarios.clear()
+            self.cbox_scenarios.addItems(groups)
+            self.cbox_metric.clear()
+            self.cbox_metric.addItems(groupsOfGroups)
+        else:
+            pass
+
+        #here we are gonna get the entities and the time of the netCDF file and set them into a QComboBox if the top level is clicked
+        #we get the time of the netCDF file
+        time = ncFile.variables['time']
+        timeUnits = time.units
+        timeCalendar = time.calendar
+        time = nc.num2date(time[:], timeUnits, timeCalendar)
+
+        #we set the time into the QComboBox
+        self.cbox_time.clear()
+        self.cbox_time.addItems([str(i) for i in time])
+        
+        #we get the entities
+        self.cbox_entity.clear()
+        entities = ncFile.variables['entity']
+        entityScope = entities.ebv_entity_scope.split(',')
+        numberOfEntities = len(entities)
+        #we set the entity_scope and the number of the entity into the QComboBox
+        #self.cbox_entity.addItems([entityScope[i] + " " + str(i) for i in range(numberOfEntities)])
+        
+        #we set the entities into the QComboBox
+        self.cbox_entity.addItems(entityScope)
+
+
+        #we close the netCDF file
+        ncFile.close()
+        
+    def showInfo(self):
+        """this function shows first the name of the file and the global attributes and then if a varible is clicked delete the info and add the attributes of the selected variable"""
+        self.text_info.clear()
+        #we get the path from the text space
+        path = self.text_set.text()
+        ncFile = nc.Dataset(path, 'r', format='NETCDF4')
+        ncFileName = os.path.basename(path)
+        ncFileTitle = ncFile.title
+        ncFileGlobalAttributes = list(ncFile.ncattrs())
+        
+        #when we click on the top level item we show the name of the file, title and the global attributes
+        if self.tree_data.currentItem().parent() == None:
+            self.text_info.clear()
+            self.text_info.append("File name: " + ncFileName)
+            self.text_info.append("Title: " + ncFileTitle)
+            self.text_info.append("Global attributes:")
+            for i in range(len(ncFileGlobalAttributes)):
+                self.text_info.append("-- " + ncFileGlobalAttributes[i] + ": " + str(ncFile.getncattr(ncFileGlobalAttributes[i])))
+                
+        #when we click on a group we show the name of the group and the attributes of the group and if we click on a variable of the group we show the attributes of the variable
+        elif self.tree_data.currentItem().parent().parent() == None:
+            self.text_info.clear()
+            self.text_info.append("File name: " + ncFileName)
+            self.text_info.append("Title: " + ncFileTitle)
+            self.text_info.append("Group name: " + self.tree_data.currentItem().text(0))
+            self.text_info.append("Long name: " + self.tree_data.currentItem().text(1))
+            self.text_info.append("Attributes:")
+            for i in range(len(ncFile.groups[self.tree_data.currentItem().text(0)].ncattrs())):
+                self.text_info.append("-- " + ncFile.groups[self.tree_data.currentItem().text(0)].ncattrs()[i] + ": " + str(ncFile.groups[self.tree_data.currentItem().text(0)].getncattr(ncFile.groups[self.tree_data.currentItem().text(0)].ncattrs()[i])))   
+        
+        #when we click on a variable of the group and the attributes of the varibales
+        else:
+            self.text_info.append("File name: " + ncFileName)
+            self.text_info.append("Title: " + ncFileTitle)
+            self.text_info.append("Variable name: " + self.tree_data.currentItem().text(0))
+            self.text_info.append("Long name: " + self.tree_data.currentItem().text(1))
+            self.text_info.append("Attributes:")
+            variableAttributes = list(ncFile.groups[self.tree_data.currentItem().parent().text(0)].variables[self.tree_data.currentItem().text(0)].ncattrs())
+            for i in range(len(variableAttributes)):
+                self.text_info.append("-- " + variableAttributes[i] + ": " + str(ncFile.groups[self.tree_data.currentItem().parent().text(0)].variables[self.tree_data.currentItem().text(0)].getncattr(variableAttributes[i])))
+
+        #we close the netCDF file
+        ncFile.close()
+
+
+    def displayData(self):
+        """this fuction get the data of each ebv_cube and add it to the map"""
+        path = self.text_set.text() #we get the path from the text space
+        ncFile = nc.Dataset(path, 'r', format='NETCDF4') #we are gonna open the nedCDF file with the netCDF4 library
+        ncFileName = os.path.basename(path) #We get the name of the netCDF file to show it in the GUI
+        #get part of the name of the netCDF file
+        ncFileName = ncFileName.split('_')
+        ncFileName = ncFileName[0] + '_' + ncFileName[1] + '_' + ncFileName[2]
+        nameOfRasterLayer =  ncFileName + "_entity: " + self.cbox_entity.currentText() + "_time: " + self.cbox_time.currentText() #we get the name of the raster layer
+        
+        #time
+        #we get the time 
+        time = ncFile.variables['time']
+        timeUnits = time.units 
+        timeCalendar = time.calendar
+        time = nc.num2date(time[:], timeUnits, timeCalendar)
+        time = [str(i) for i in time] #we have to convert the time into a string
+        max_time = len(time) #we get the length of the time
+      
+        #time selected in the QComboBox
+        timeSelected = self.cbox_time.currentText()
+        timeIndex = time.index(timeSelected) #we get the index of the time selected
+        
+
+        #Entity
+        #we get the entities
+        entity = ncFile.variables['entity']
+        entityScope = entity.ebv_entity_scope.split(',') #we get the name of the entities
+
+        #entity selected in the QComboBox
+        entitySelected = self.cbox_entity.currentText()
+        entityIndex = entityScope.index(entitySelected) #we get the index of the entity selected
+        
+        
+        #get the scenarios and the metrics from the interface
+        #scenarios
+        scenarioSelected = self.cbox_scenarios.currentText()
+        scenarioIndex = self.cbox_scenarios.currentIndex()
+        #metrics
+        metricSelected = self.cbox_metric.currentText()
+        metricIndex = self.cbox_metric.currentIndex()
+        
+        uri = r'NETCDF:"'+ path + '":' + metricSelected + '/ebv_cube'
+        
+        #if there just metrics and no scenarios we have to create a uri with the metric selected in the QComboBox
+        # if scenarioIndex == 0:
+        #     uri = r'NETCDF:"'+ path + '":' + metricSelected + '/ebv_cube'
+        # else:
+        #     uri = r'NETCDF:"'+ path + '":'+ scenarioSelected + '/' + metricSelected + '/ebv_cube'
+        
+      
+
+        #load the raster layer into the QGIS canvas
+        rasterLayer = QgsRasterLayer(uri, nameOfRasterLayer, "gdal")
+        print(rasterLayer.isValid())
+        
+        
+        #calculate the band number
+        band = (entityIndex-1)*max_time+ timeIndex
+        
+        
+        #get the min and the max value of the band
+        dp = rasterLayer.dataProvider()
+        stats = dp.bandStatistics(band)
+        min = stats.minimumValue
+        max = stats.maximumValue
+
+        #build the color ramp
+        colorRamp = QgsColorRampShader(min, max)
+        colorRamp.setColorRampType(QgsColorRampShader.Interpolated)
+        colorRamp.setColorRampItemList([QgsColorRampShader.ColorRampItem(min, QColor(0, 0, 255)), 
+                                        QgsColorRampShader.ColorRampItem(max, QColor(255, 0, 0))])
+        #build the shader
+        shader = QgsRasterShader()
+        shader.setRasterShaderFunction(colorRamp)
+
+        #build the renderer
+        renderer = QgsSingleBandPseudoColorRenderer(rasterLayer.dataProvider(), band, shader) #we have to put the band number
+        rasterLayer.setRenderer(renderer)   
+
+        #add the raster layer to the map
+        QgsProject.instance().addMapLayer(rasterLayer)
+
+        #close the netCDF file
+        ncFile.close()
+
+       
+        
+       
+        
+
+       
+        
diff --git a/__init__.py b/__init__.py
index d0ed9db..5bd9042 100644
--- a/__init__.py
+++ b/__init__.py
@@ -1,8 +1,8 @@
 #the __init__ gives the construction order for the plugin
-from .netCDF_visualizer import netCDFVisualizer
+from .EBVCubeVisualizer import EBVCubeVisualizer
 
 def classFactory(iface):
-    plugin = netCDFVisualizer(iface)
+    plugin = EBVCubeVisualizer(iface)
     return plugin
 
 
diff --git a/metadata.txt b/metadata.txt
index b5c479d..7cfd4d6 100644
--- a/metadata.txt
+++ b/metadata.txt
@@ -1,5 +1,5 @@
 [general]
-name=netCDFVisualizer
+name=EBVCubeVisualizer
 email=e.oceguera@gmx.de
 author=Emmanuel Oceguera-Conchas
 qgisMinimumVersion=3.0
diff --git a/styles/raster_style.qml b/styles/raster_style.qml
new file mode 100644
index 0000000..5313c2b
--- /dev/null
+++ b/styles/raster_style.qml
@@ -0,0 +1,91 @@
+<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
+<qgis maxScale="0" minScale="1e+08" hasScaleBasedVisibilityFlag="0" styleCategories="AllStyleCategories" version="3.24.2-Tisler">
+  <flags>
+    <Identifiable>1</Identifiable>
+    <Removable>1</Removable>
+    <Searchable>1</Searchable>
+    <Private>0</Private>
+  </flags>
+  <temporal enabled="0" mode="0" fetchMode="0">
+    <fixedRange>
+      <start></start>
+      <end></end>
+    </fixedRange>
+  </temporal>
+  <customproperties>
+    <Option type="Map">
+      <Option name="WMSBackgroundLayer" type="bool" value="false"/>
+      <Option name="WMSPublishDataSourceUrl" type="bool" value="false"/>
+      <Option name="embeddedWidgets/count" type="int" value="0"/>
+      <Option name="identify/format" type="QString" value="Value"/>
+    </Option>
+  </customproperties>
+  <pipe-data-defined-properties>
+    <Option type="Map">
+      <Option name="name" type="QString" value=""/>
+      <Option name="properties"/>
+      <Option name="type" type="QString" value="collection"/>
+    </Option>
+  </pipe-data-defined-properties>
+  <pipe>
+    <provider>
+      <resampling maxOversampling="2" zoomedInResamplingMethod="nearestNeighbour" enabled="false" zoomedOutResamplingMethod="nearestNeighbour"/>
+    </provider>
+    <rasterrenderer nodataColor="" type="singlebandpseudocolor" opacity="1" classificationMin="-9.9112749" band="9" alphaBand="-1" classificationMax="19.6030865">
+      <rasterTransparency/>
+      <minMaxOrigin>
+        <limits>MinMax</limits>
+        <extent>WholeRaster</extent>
+        <statAccuracy>Estimated</statAccuracy>
+        <cumulativeCutLower>0.02</cumulativeCutLower>
+        <cumulativeCutUpper>0.98</cumulativeCutUpper>
+        <stdDevFactor>2</stdDevFactor>
+      </minMaxOrigin>
+      <rastershader>
+        <colorrampshader colorRampType="INTERPOLATED" clip="0" maximumValue="19.6030865" classificationMode="1" minimumValue="-9.9112749000000004" labelPrecision="6">
+          <colorramp name="[source]" type="gradient">
+            <Option type="Map">
+              <Option name="color1" type="QString" value="17,116,177,255"/>
+              <Option name="color2" type="QString" value="189,37,40,255"/>
+              <Option name="direction" type="QString" value="cw"/>
+              <Option name="discrete" type="QString" value="0"/>
+              <Option name="rampType" type="QString" value="gradient"/>
+              <Option name="spec" type="QString" value="rgb"/>
+              <Option name="stops" type="QString" value="0.175481;118,185,169,255;rgb;ccw:0.324519;171,221,164,255;rgb;cw:0.496394;243,243,61,255;rgb;cw:0.680288;253,174,97,255;rgb;cw:0.832933;230,84,55,255;rgb;ccw"/>
+            </Option>
+            <prop k="color1" v="17,116,177,255"/>
+            <prop k="color2" v="189,37,40,255"/>
+            <prop k="direction" v="cw"/>
+            <prop k="discrete" v="0"/>
+            <prop k="rampType" v="gradient"/>
+            <prop k="spec" v="rgb"/>
+            <prop k="stops" v="0.175481;118,185,169,255;rgb;ccw:0.324519;171,221,164,255;rgb;cw:0.496394;243,243,61,255;rgb;cw:0.680288;253,174,97,255;rgb;cw:0.832933;230,84,55,255;rgb;ccw"/>
+          </colorramp>
+          <item color="#1174b1" label="-9.911275" value="-9.911274909973145" alpha="255"/>
+          <item color="#90cba6" label="-2.532685" value="-2.532684564590454" alpha="255"/>
+          <item color="#f3f23e" label="4.845906" value="4.845905780792236" alpha="255"/>
+          <item color="#f2854e" label="12.224496" value="12.224496126174927" alpha="255"/>
+          <item color="#bd2528" label="19.603086" value="19.603086471557617" alpha="255"/>
+          <rampLegendSettings direction="0" useContinuousLegend="1" minimumLabel="" orientation="2" suffix="" prefix="" maximumLabel="">
+            <numericFormat id="basic">
+              <Option type="Map">
+                <Option name="decimal_separator" type="QChar" value=""/>
+                <Option name="decimals" type="int" value="6"/>
+                <Option name="rounding_type" type="int" value="0"/>
+                <Option name="show_plus" type="bool" value="false"/>
+                <Option name="show_thousand_separator" type="bool" value="true"/>
+                <Option name="show_trailing_zeros" type="bool" value="false"/>
+                <Option name="thousand_separator" type="QChar" value=""/>
+              </Option>
+            </numericFormat>
+          </rampLegendSettings>
+        </colorrampshader>
+      </rastershader>
+    </rasterrenderer>
+    <brightnesscontrast brightness="0" contrast="0" gamma="1"/>
+    <huesaturation colorizeOn="0" grayscaleMode="0" colorizeStrength="100" saturation="0" invertColors="0" colorizeGreen="128" colorizeRed="255" colorizeBlue="128"/>
+    <rasterresampler maxOversampling="2"/>
+    <resamplingStage>resamplingFilter</resamplingStage>
+  </pipe>
+  <blendMode>0</blendMode>
+</qgis>
-- 
GitLab