Skip to content
Snippets Groups Projects
Commit 6ddb800c authored by Emmanuel Heriberto Oceguera Conchas's avatar Emmanuel Heriberto Oceguera Conchas
Browse files

name changed

parent 9e418d51
No related branches found
No related tags found
No related merge requests found
'''
/****************************************************************************************
*
*
*
*
*
****************************************************************************************/
/****************************************************************************************
* 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()
<?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>
'''
/****************************************************************************************
* 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()
#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
......
[general]
name=netCDFVisualizer
name=EBVCubeVisualizer
email=e.oceguera@gmx.de
author=Emmanuel Oceguera-Conchas
qgisMinimumVersion=3.0
......
<!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>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment