示例#1
0
    def __init__(self, iface):

        self.iface = iface
        self.prefix = ''
        self.variables = None
        self.dim_names = []
        self.dim_values = dict()
        self.dim_values2 = dict()
        self.dim_def = dict()
        self.dim_band = dict()
        self.dim1Count = 0
        self.dim2Count = 0
        self.layerCrs = QgsCoordinateReferenceSystem()
        self.selectedCrs = QgsCoordinateReferenceSystem()

        QDialog.__init__(self)
        # Set up the user interface from Designer.
        self.ui = Ui_NetCDFBrowser()
        self.ui.setupUi(self)

        self.ui.cboCrs.clear()
        self.ui.cboCrs.insertItem(0, self.tr("Layer (None)"))
        self.ui.cboCrs.insertItem(1, self.tr("Project (None)"))
        self.ui.cboCrs.insertItem(2, self.tr("Selected (None)"))

        QObject.connect(self.ui.cboVars,
                        SIGNAL("currentIndexChanged(QString)"),
                        self.updateVariable)
    def __init__(self, iface):

        self.iface = iface
        self.prefix = ''
        self.variables = None
        self.dim_names = []
        self.dim_values = dict()
        self.dim_values2 = dict()
        self.dim_def = dict()
        self.dim_band = dict()
        self.dim1Count=0
        self.dim2Count=0
        self.layerCrs = QgsCoordinateReferenceSystem()
        self.selectedCrs = QgsCoordinateReferenceSystem()

        QDialog.__init__(self)
        # Set up the user interface from Designer.
        self.ui = Ui_NetCDFBrowser()
        self.ui.setupUi(self)

        self.ui.cboCrs.clear()
        self.ui.cboCrs.insertItem(0, self.tr("Layer (None)"))
        self.ui.cboCrs.insertItem(1, self.tr("Project (None)"))
        self.ui.cboCrs.insertItem(2, self.tr("Selected (None)"))

        QObject.connect(self.ui.cboVars, SIGNAL("currentIndexChanged(QString)"), self.updateVariable)   
class NetCDFBrowserDialog(QDialog):
    def __init__(self, iface):

        self.iface = iface
        self.prefix = ''
        self.variables = None
        self.dim_names = []
        self.dim_values = dict()
        self.dim_values2 = dict()
        self.dim_def = dict()
        self.dim_band = dict()
        self.dim1Count=0
        self.dim2Count=0
        self.layerCrs = QgsCoordinateReferenceSystem()
        self.selectedCrs = QgsCoordinateReferenceSystem()

        QDialog.__init__(self)
        # Set up the user interface from Designer.
        self.ui = Ui_NetCDFBrowser()
        self.ui.setupUi(self)

        self.ui.cboCrs.clear()
        self.ui.cboCrs.insertItem(0, self.tr("Layer (None)"))
        self.ui.cboCrs.insertItem(1, self.tr("Project (None)"))
        self.ui.cboCrs.insertItem(2, self.tr("Selected (None)"))

        QObject.connect(self.ui.cboVars, SIGNAL("currentIndexChanged(QString)"), self.updateVariable)   


    def exec_(self):
        self.on_pbnFileName_pressed()
        QDialog.exec_(self)


    def on_pbnFileName_pressed(self):
        fileName = QFileDialog.getOpenFileName(self, self.tr("Open File"), "",
                   self.tr("netCDF Files (*.nc *.cdf *.nc2 *.nc4)"));
        if fileName is not None:
            self.ui.leFileName.setText( fileName )
            self.updateFile()


    # TODO add a addLayers() function
    def addLayer(self,fileName,var,band):
        if debug>0:
            print('addLayer(%s,%s,%s)' % (fileName,var,band))

        uri = 'NETCDF:"%s":%s' % (fileName, var)
        #name = 'NETCDF:"%s":%s#%d' % (QFileInfo(fileName).fileName(), var, band)
        name = '%s_var=%s' % (QFileInfo(fileName).fileName(), var) if var else QFileInfo(fileName).fileName()
        if band:
            band = int(band)
            if len(self.dim_names) >= 1:
                values2 = self.dim_values2[self.dim_names[0]] if self.dim_names[0] in self.dim_values2 else None
                if values2 and len(values2) >= self.dim_band[band][0] :
                    tmp = str(values2[self.dim_band[band][0]-1])
                else:
                    tmp = str(self.dim_band[band][0]).zfill(int(math.ceil(math.log(self.dim_def[self.dim_names[0]][0],10))))
                name = "%s_%s=%s" % (name,self.dim_names[0],tmp)
            if len(self.dim_names) >= 2 :
                values2 = self.dim_values2[self.dim_names[1]] if self.dim_names[1] in self.dim_values2 else None
                if values2 and len(values2) >= self.dim_band[band][1] :
                    tmp = str(values2[self.dim_band[band][1]-1])
                else:
                    tmp = str(self.dim_band[band][1]).zfill(int(math.ceil(math.log(self.dim_def[self.dim_names[1]][0],10))))
                name = "%s_%s=%s" % (name,self.dim_names[1],tmp)
            num_bands = max(self.dim1Count,1) * max(self.dim1Count,1)
            tmp = str(band).zfill(int(math.ceil(math.log(num_bands,10))))
            name = '%s_band=%s' % (name, tmp)

        # temporarily override /Projections/defaultBehaviour to avoid dialog prompt
        # this is taken from qgsbrowserdockwidget.cpp
        # TODO - integrate this into qgis core
        if self.ui.cboCrs.currentIndex() != 0:
            settings = QSettings()
            defaultProjectionOption = settings.value( "/Projections/defaultBehaviour", "prompt" )
            if defaultProjectionOption == "prompt":
                settings.setValue( "/Projections/defaultBehaviour", "useProject" )

        rlayer = QgsRasterLayer( uri, name )
        if rlayer is None or not rlayer.isValid():
            print('NetCDF Browser Plugin : raster %s failed to load' % uri)
            return

        # restore /Projections/defaultBehaviour
        if self.ui.cboCrs.currentIndex() != 0:
            if defaultProjectionOption == "prompt":
                settings.setValue( "/Projections/defaultBehaviour", defaultProjectionOption );

        if debug>0:
            print('created layer')

        # set layer CRS
        if self.ui.cboCrs.currentIndex() == 1:
            # this has changed in 2.4 ... 
            rlayer.setCrs( self.iface.mapCanvas().mapRenderer().destinationCrs() )
        elif self.ui.cboCrs.currentIndex() == 2:
            rlayer.setCrs( self.selectedCrs )

        #rtype = self.ui.cboRenderer.currentIndex() == 0:
        rtype = 0
        # set rendering to gray so only selected band is shown
        if rtype == 0 and band:
            rlayer.setDrawingStyle("SingleBandGray")
            renderer = rlayer.renderer()
            renderer.setGrayBand(band)
        rlayer.setDefaultContrastEnhancement()

        QgsMapLayerRegistry.instance().addMapLayers([rlayer])


    def on_pbnAddSelection_pressed(self):
        if debug>0:
            print('on_pbnAddSelection_pressed')
            #print(str(len(self.dim_names)) + " - " + str(self.ui.cbxMultiSelection.isChecked()))

        if len(self.dim_names) == 0:

            fileName = self.ui.leFileName.text()
            var = self.ui.cboVars.currentText()
            band = self.ui.leBandSelection.text()
            self.addLayer(fileName,var,band)

        else:

            if len( self.ui.leBandSelection.text() ) == 0:
                return

            fileName = self.ui.leFileName.text()
            var = self.ui.cboVars.currentText()

            for band_str in self.ui.leBandSelection.text().strip().split(' '):
                self.addLayer(fileName,var,band_str)


    def updateFile(self):
        self.clear()
        fileName = self.ui.leFileName.text()
        if debug>0:
            print('updateFile '+fileName)
        if fileName == '':
            return

        self.prefix = ''
        self.variables = []

        gdal.PushErrorHandler('CPLQuietErrorHandler')
        ds = gdal.Open(fileName)
        gdal.PopErrorHandler()
        if ds is None:
            return
        md = ds.GetMetadata("SUBDATASETS")
        ds = None

        for key in sorted(md.iterkeys()):
            #SUBDATASET_1_NAME=NETCDF:"file.nc":var
            if re.match('^SUBDATASET_[0-9]+_NAME$', key) is None:
                continue
            m = re.search('^(NETCDF:".+"):(.+)', md[key])
            if m is None:
                continue
            self.prefix = m.group(1)
            self.variables.append(m.group(2))

        if debug>0:
            print('prefix: '+str(self.prefix))
            print('variables: '+str(self.variables))
        self.ui.cboVars.blockSignals(True)
        self.ui.cboVars.clear()
        for var in self.variables:
            self.ui.cboVars.addItem( var )
        self.updateVariable()
        self.ui.cboVars.blockSignals(False)

        if debug>0:
            print('done updateFile '+fileName)


    def clear(self):
        if debug>0:
            print('clear')
        self.ui.lblDim1.setText('     -     ')
        self.ui.lblDim2.setText('     -     ')
        self.ui.leBandSelection.clear()
        if self.ui.pbnDim1.menu():
            QObject.disconnect(self.ui.pbnDim1.menu(), SIGNAL("triggered(QAction *)"), self.on_pbnDimx_triggered)   
            self.ui.pbnDim1.setMenu(None)
        if self.ui.pbnDim2.menu():
            QObject.disconnect(self.ui.pbnDim2.menu(), SIGNAL("triggered(QAction *)"), self.on_pbnDimx_triggered)   
            self.ui.pbnDim2.setMenu(None)


    def warning(self):
        gdal_version = gdal.VersionInfo("RELEASE_NAME")
        if debug>1:
            print("gdal version: " + str(gdal.VersionInfo("VERSION_NUM")))
        if int(gdal.VersionInfo("VERSION_NUM")) < 1000000:
            msg = self.tr("No extra dimensions found, make sure you are using\nGDAL >= 1.10\nYou seem to have "+gdal_version)
        else:
            msg = self.tr("No extra dimensions found.")
        QMessageBox.warning(self, self.tr("NetCDF Browser Plugin"), msg, QMessageBox.Close)

    def warning2(self):
        print("NetCDFBrowser: No extra dimensions found, but empty dimensions may have been removed")

    def updateVariable(self):
        dim_map = dict()
        self.dim_names = []
        self.dim_values = dict()
        self.dim_values2 = dict()
        self.dim_def = dict()
        self.dim_band = dict()
        self.dim1Count = 0
        self.dim2Count = 0
        self.clear()
        uri = 'NETCDF:"%s":%s' % (self.ui.leFileName.text(), self.ui.cboVars.currentText())

        if debug>0:
            print('updateVariable '+str(uri))

        #look for extra dim definitions
        #  NETCDF_DIM_EXTRA={time,tile}
        #  NETCDF_DIM_tile_DEF={3,6}
        #  NETCDF_DIM_tile_VALUES={1,2,3}
        #  NETCDF_DIM_time_DEF={12,6}
        #  NETCDF_DIM_time_VALUES={1,32,60,91,121,152,182,213,244,274,305,335}

        # open file and get basic info
        gdal.PushErrorHandler('CPLQuietErrorHandler')
        ds = gdal.Open(uri)
        gdal.PopErrorHandler()
        if ds is None:
            return
        wkt = ds.GetProjection()
        md = ds.GetMetadata()
        ds = None
        if md is None:
            return

        # update CRS selectors
        projectCrs = self.iface.mapCanvas().mapRenderer().destinationCrs()
        self.ui.cboCrs.setItemText(1, 
                                   self.tr( "Project" ) + " (%s, %s)" % (projectCrs.description(), projectCrs.authid()) )
        
        if not wkt or not self.layerCrs.createFromWkt(wkt):
                self.layerCrs = QgsCoordinateReferenceSystem()
        if debug > 0:
            print('wkt: '+wkt+' layer desc:'+self.layerCrs.description())

        # if layer has valid crs, use that, if not use selected crs
        if self.layerCrs.description():
            self.ui.cboCrs.setItemText(0, 
                                       self.tr( "Layer" ) + " (%s, %s)" % (self.layerCrs.description(), self.layerCrs.authid()) )
            self.ui.cboCrs.setCurrentIndex(0)
        else:
            self.ui.cboCrs.setItemText(0, self.tr("Layer (None)"))
            if self.selectedCrs.description():
                self.ui.cboCrs.setItemText(2, 
                                           self.tr( "Selected" ) + " (%s, %s)" % (self.selectedCrs.description(), self.selectedCrs.authid()) )
            else:
                self.ui.cboCrs.setItemText(2, self.tr("Selected (None)"))
            self.ui.cboCrs.setCurrentIndex(2)

        ds = None

        # iterate over all md items looking for dim info
        for key in sorted(md.iterkeys()):
            if key.startswith('NETCDF_DIM_'):
                line="%s=%s" % (key,md[key])
                m = re.search('^(NETCDF_DIM_.+)={(.+)}', line)
                if m is not None:
                    dim_map[ m.group(1) ] = m.group(2)

        if not 'NETCDF_DIM_EXTRA' in dim_map:
            self.warning()
            return
        
        tok = dim_map['NETCDF_DIM_EXTRA']
        if tok is not None:
            for dim in tok.split(','):
                self.dim_names.append( dim )
                tok2 = dim_map.get('NETCDF_DIM_'+dim+'_VALUES')
                self.dim_values[ dim ] = []
                if tok2 is not None:
                    for s in tok2.split(','):
                        self.dim_values[ dim ].append(num(s))
                tok2 = dim_map.get('NETCDF_DIM_'+dim+'_DEF')
                self.dim_def[ dim ] = []
                if tok2 is not None:
                    for s in tok2.split(','):
                        self.dim_def[ dim ].append(num(s))

        # remove any dims which have only 1 element
        dim_names = self.dim_names
        self.dim_names = []
        for dim in dim_names:
            if self.dim_def[dim][0] <= 1:
                del self.dim_values[dim]
                del self.dim_def[dim]
            else:
                self.dim_names.append(dim)

        # transform time dimensions - currently requires netcdftime from python-netcdf4              
        if has_netcdftime:
            for dim in dim_names:
                #dim+"#standard_name" in md and md[dim+"#standard_name"] == "time":
                if dim in self.dim_values:
                    if dim+"#units" in md:
                        timestr = md[ dim+"#units" ]
                        units = timestr.split()[0].lower()
                        if units in _units:
                            try:
                                dates = num2date(self.dim_values[dim],units=timestr)
                            except ValueError:
                                continue
                            self.dim_values2[ dim ] = []
                            only_days = True
                            for date in dates:
                                val = date.isoformat(" ") # equivalent to strftime("%Y-%m-%d %H:%M:%S")
                                if not val.endswith(" 00:00:00"):
                                    only_days = False
                                self.dim_values2[ dim ].append(val)
                            if only_days:
                                for i in range(0,len(self.dim_values2[ dim ])):
                                    self.dim_values2[dim][i] = self.dim_values2[dim][i][0:10]

        if debug>1:
            print(str(dim_map))
            print(str(self.dim_names))
            print(str(self.dim_def))
            print(str(self.dim_values))
            print(str(self.dim_values2))


        # update UI
        self.ui.pbnDim1.setEnabled(False)
        self.ui.pbnDim2.setEnabled(False)

        if len(self.dim_names) > 0:
            dim = self.dim_names[0]
            self.ui.lblDim1.setText( dim )
            menu = MyMenu()
            action = QAction(self.tr('all/none'),menu)
            action.setCheckable(True)
            menu.addAction(action)
            for i in range(0,len(self.dim_values[dim])):
                self.dim2Count = self.dim2Count + 1
                value = self.dim_values2[dim][i] if dim in self.dim_values2 else self.dim_values[dim][i]
                action = QAction(str(value),menu)
                action.setCheckable(True)
                menu.addAction(action)                
            self.ui.pbnDim1.setMenu(menu)
            QObject.connect(self.ui.pbnDim1.menu(), SIGNAL("triggered(QAction *)"), self.on_pbnDimx_triggered)   
            # click first element of each dim
            if len(menu.actions()) > 1:
                menu.actions()[1].setChecked(True)
            self.ui.pbnDim1.setEnabled(True)

        if len(self.dim_names) > 1:
            dim = self.dim_names[1]
            self.ui.lblDim2.setText( dim )
            menu = MyMenu()
            action = QAction(self.tr('all/none'),menu)
            action.setCheckable(True)
            menu.addAction(action)
            for i in range(0,len(self.dim_values[dim])):
                self.dim2Count = self.dim2Count + 1
                value = self.dim_values[dim][i]
                action = QAction(str(value),menu)
                action.setCheckable(True)
                menu.addAction(action)
            self.ui.pbnDim2.setMenu(menu)
            QObject.connect(self.ui.pbnDim2.menu(), SIGNAL("triggered(QAction *)"), self.on_pbnDimx_triggered)   
            # click first element of each dim
            if len(menu.actions()) > 1:
                menu.actions()[1].setChecked(True)
            self.ui.pbnDim2.setEnabled(True)

        # make sure we found something, if not notify user
        if len(self.dim_names) == 0:
            self.warning2()
        self.updateURI()
        self.updateDims()


    def updateDims(self):
        # TODO minimize calls to this fct
        if debug>0:
            print('updateDims')
        self.updateDimsMulti()
            
    def updateDimsMulti(self):
        # update multi-band selection
        self.ui.leBandSelection.clear()
        if self.ui.pbnDim1.menu() is None and self.ui.pbnDim2.menu() is None:
            return
        sel1 = []
        i=0
        actions = [] if self.ui.pbnDim1.menu() is None else self.ui.pbnDim1.menu().actions()
        for action in actions:
            if action.text() != self.tr('all/none'):
                if action.isChecked():
                    sel1.append(i)
                i = i + 1
        sel2 = []
        i=0
        actions = [] if self.ui.pbnDim2.menu() is None else self.ui.pbnDim2.menu().actions()
        for action in actions:
            if action.text() != self.tr('all/none'):
                if action.isChecked():
                    sel2.append(i)
                i = i + 1

        sel_str = ''
        for dim1val in sel1:
            if self.ui.pbnDim2.menu() is None:
                band = dim1val+1
                self.dim_band[band] = [dim1val+1]
                sel_str = '%s%d ' % (sel_str,band)
            else:
                for dim2val in sel2:
                    band = self.bandNo(dim1val,dim2val)
                    self.dim_band[band] = [dim1val+1,dim2val+1]
                    sel_str = '%s%d ' % (sel_str,band)

        self.ui.leBandSelection.setText(sel_str)


    def bandNo(self,dim1val,dim2val):
        band = 0
        if dim2val > -1 :
            band += dim2val+1
        if dim1val > -1 :
            if len(self.dim_def) > 0 and len(self.dim_names) > 0:
                band += (dim1val) * int(self.dim_def[self.dim_names[1]][0])
        return band


    def updateURI(self):
        if debug>0:
            print('updateURI')
        # update URI
        fileInfo = QFileInfo(self.ui.leFileName.text())
        uri = 'NETCDF:"%s":%s' % (fileInfo.fileName(), self.ui.cboVars.currentText())
        self.ui.leURI.setText(uri)


    def on_pbnDimx_triggered(self,action):
        if action in self.ui.pbnDim1.menu().actions():
            pbn = self.ui.pbnDim1
        elif action in self.ui.pbnDim2.menu().actions():
            pbn = self.ui.pbnDim2
        else:
            return
        # 'all/none' action selects all/none
        if action.text() == self.tr('all/none'):
            pbn.blockSignals(True)
            for act in pbn.menu().actions():
                if act.text() != self.tr('all/none'):
                    act.setChecked(action.isChecked())
            pbn.blockSignals(False)
        
        # update selection
        self.updateDims()


    def on_pbnCrs_pressed(self):
        selector = QgsGenericProjectionSelector(self)
        selector.setMessage();
        if self.layerCrs.description():
            selector.setSelectedCrsId( self.layerCrs.srsid() );
        elif self.selectedCrs.description():
            selector.setSelectedCrsId( self.selectedCrs.srsid() );
        if selector.exec_():
            self.selectedCrs.createFromId( selector.selectedCrsId(), QgsCoordinateReferenceSystem.InternalCrsId );
            self.ui.cboCrs.setCurrentIndex(2)

        if self.selectedCrs.description():
            self.ui.cboCrs.setItemText(2, 
                                       self.tr( "Selected" ) + " (%s, %s)" % (self.selectedCrs.description(), self.selectedCrs.authid()) )
        else:
            self.ui.cboCrs.setItemText(2, self.tr("Selected (None)"))
示例#4
0
class NetCDFBrowserDialog(QDialog):
    def __init__(self, iface):

        self.iface = iface
        self.prefix = ''
        self.variables = None
        self.dim_names = []
        self.dim_values = dict()
        self.dim_values2 = dict()
        self.dim_def = dict()
        self.dim_band = dict()
        self.dim1Count = 0
        self.dim2Count = 0
        self.layerCrs = QgsCoordinateReferenceSystem()
        self.selectedCrs = QgsCoordinateReferenceSystem()

        QDialog.__init__(self)
        # Set up the user interface from Designer.
        self.ui = Ui_NetCDFBrowser()
        self.ui.setupUi(self)

        self.ui.cboCrs.clear()
        self.ui.cboCrs.insertItem(0, self.tr("Layer (None)"))
        self.ui.cboCrs.insertItem(1, self.tr("Project (None)"))
        self.ui.cboCrs.insertItem(2, self.tr("Selected (None)"))

        QObject.connect(self.ui.cboVars,
                        SIGNAL("currentIndexChanged(QString)"),
                        self.updateVariable)

    def exec_(self):
        self.on_pbnFileName_pressed()
        QDialog.exec_(self)

    def on_pbnFileName_pressed(self):
        fileName = QFileDialog.getOpenFileName(
            self, self.tr("Open File"), "",
            self.tr("netCDF Files (*.nc *.cdf *.nc2 *.nc4)"))
        if fileName is not None:
            self.ui.leFileName.setText(fileName)
            self.updateFile()

    # TODO add a addLayers() function
    def addLayer(self, fileName, var, band):
        if debug > 0:
            print('addLayer(%s,%s,%s)' % (fileName, var, band))

        uri = 'NETCDF:"%s":%s' % (fileName, var)
        #name = 'NETCDF:"%s":%s#%d' % (QFileInfo(fileName).fileName(), var, band)
        name = '%s_var=%s' % (QFileInfo(fileName).fileName(),
                              var) if var else QFileInfo(fileName).fileName()
        if band:
            band = int(band)
            if len(self.dim_names) >= 1:
                values2 = self.dim_values2[self.dim_names[
                    0]] if self.dim_names[0] in self.dim_values2 else None
                if values2 and len(values2) >= self.dim_band[band][0]:
                    tmp = str(values2[self.dim_band[band][0] - 1])
                else:
                    tmp = str(self.dim_band[band][0]).zfill(
                        int(
                            math.ceil(
                                math.log(self.dim_def[self.dim_names[0]][0],
                                         10))))
                name = "%s_%s=%s" % (name, self.dim_names[0], tmp)
            if len(self.dim_names) >= 2:
                values2 = self.dim_values2[self.dim_names[
                    1]] if self.dim_names[1] in self.dim_values2 else None
                if values2 and len(values2) >= self.dim_band[band][1]:
                    tmp = str(values2[self.dim_band[band][1] - 1])
                else:
                    tmp = str(self.dim_band[band][1]).zfill(
                        int(
                            math.ceil(
                                math.log(self.dim_def[self.dim_names[1]][0],
                                         10))))
                name = "%s_%s=%s" % (name, self.dim_names[1], tmp)
            num_bands = max(self.dim1Count, 1) * max(self.dim1Count, 1)
            tmp = str(band).zfill(int(math.ceil(math.log(num_bands, 10))))
            name = '%s_band=%s' % (name, tmp)

        # temporarily override /Projections/defaultBehaviour to avoid dialog prompt
        # this is taken from qgsbrowserdockwidget.cpp
        # TODO - integrate this into qgis core
        if self.ui.cboCrs.currentIndex() != 0:
            settings = QSettings()
            defaultProjectionOption = settings.value(
                "/Projections/defaultBehaviour", "prompt")
            if defaultProjectionOption == "prompt":
                settings.setValue("/Projections/defaultBehaviour",
                                  "useProject")

        rlayer = QgsRasterLayer(uri, name)
        if rlayer is None or not rlayer.isValid():
            print('NetCDF Browser Plugin : raster %s failed to load' % uri)
            return

        # restore /Projections/defaultBehaviour
        if self.ui.cboCrs.currentIndex() != 0:
            if defaultProjectionOption == "prompt":
                settings.setValue("/Projections/defaultBehaviour",
                                  defaultProjectionOption)

        if debug > 0:
            print('created layer')

        # set layer CRS
        if self.ui.cboCrs.currentIndex() == 1:
            # this has changed in 2.4 ...
            rlayer.setCrs(
                self.iface.mapCanvas().mapRenderer().destinationCrs())
        elif self.ui.cboCrs.currentIndex() == 2:
            rlayer.setCrs(self.selectedCrs)

        #rtype = self.ui.cboRenderer.currentIndex() == 0:
        rtype = 0
        # set rendering to gray so only selected band is shown
        if rtype == 0 and band:
            rlayer.setDrawingStyle("SingleBandGray")
            renderer = rlayer.renderer()
            renderer.setGrayBand(band)
        rlayer.setDefaultContrastEnhancement()

        QgsMapLayerRegistry.instance().addMapLayers([rlayer])

    def on_pbnAddSelection_pressed(self):
        if debug > 0:
            print('on_pbnAddSelection_pressed')
            #print(str(len(self.dim_names)) + " - " + str(self.ui.cbxMultiSelection.isChecked()))

        if len(self.dim_names) == 0:

            fileName = self.ui.leFileName.text()
            var = self.ui.cboVars.currentText()
            band = self.ui.leBandSelection.text()
            self.addLayer(fileName, var, band)

        else:

            if len(self.ui.leBandSelection.text()) == 0:
                return

            fileName = self.ui.leFileName.text()
            var = self.ui.cboVars.currentText()

            for band_str in self.ui.leBandSelection.text().strip().split(' '):
                self.addLayer(fileName, var, band_str)

    def updateFile(self):
        self.clear()
        fileName = self.ui.leFileName.text()
        if debug > 0:
            print('updateFile ' + fileName)
        if fileName == '':
            return

        self.prefix = ''
        self.variables = []

        gdal.PushErrorHandler('CPLQuietErrorHandler')
        ds = gdal.Open(fileName)
        gdal.PopErrorHandler()
        if ds is None:
            return
        md = ds.GetMetadata("SUBDATASETS")
        ds = None

        for key in sorted(md.iterkeys()):
            #SUBDATASET_1_NAME=NETCDF:"file.nc":var
            if re.match('^SUBDATASET_[0-9]+_NAME$', key) is None:
                continue
            m = re.search('^(NETCDF:".+"):(.+)', md[key])
            if m is None:
                continue
            self.prefix = m.group(1)
            self.variables.append(m.group(2))

        if debug > 0:
            print('prefix: ' + str(self.prefix))
            print('variables: ' + str(self.variables))
        self.ui.cboVars.blockSignals(True)
        self.ui.cboVars.clear()
        for var in self.variables:
            self.ui.cboVars.addItem(var)
        self.updateVariable()
        self.ui.cboVars.blockSignals(False)

        if debug > 0:
            print('done updateFile ' + fileName)

    def clear(self):
        if debug > 0:
            print('clear')
        self.ui.lblDim1.setText('     -     ')
        self.ui.lblDim2.setText('     -     ')
        self.ui.leBandSelection.clear()
        if self.ui.pbnDim1.menu():
            QObject.disconnect(self.ui.pbnDim1.menu(),
                               SIGNAL("triggered(QAction *)"),
                               self.on_pbnDimx_triggered)
            self.ui.pbnDim1.setMenu(None)
        if self.ui.pbnDim2.menu():
            QObject.disconnect(self.ui.pbnDim2.menu(),
                               SIGNAL("triggered(QAction *)"),
                               self.on_pbnDimx_triggered)
            self.ui.pbnDim2.setMenu(None)

    def warning(self):
        gdal_version = gdal.VersionInfo("RELEASE_NAME")
        if debug > 1:
            print("gdal version: " + str(gdal.VersionInfo("VERSION_NUM")))
        if int(gdal.VersionInfo("VERSION_NUM")) < 1000000:
            msg = self.tr(
                "No extra dimensions found, make sure you are using\nGDAL >= 1.10\nYou seem to have "
                + gdal_version)
        else:
            msg = self.tr("No extra dimensions found.")
        QMessageBox.warning(self, self.tr("NetCDF Browser Plugin"), msg,
                            QMessageBox.Close)

    def warning2(self):
        print(
            "NetCDFBrowser: No extra dimensions found, but empty dimensions may have been removed"
        )

    def updateVariable(self):
        dim_map = dict()
        self.dim_names = []
        self.dim_values = dict()
        self.dim_values2 = dict()
        self.dim_def = dict()
        self.dim_band = dict()
        self.dim1Count = 0
        self.dim2Count = 0
        self.clear()
        uri = 'NETCDF:"%s":%s' % (self.ui.leFileName.text(),
                                  self.ui.cboVars.currentText())

        if debug > 0:
            print('updateVariable ' + str(uri))

        #look for extra dim definitions
        #  NETCDF_DIM_EXTRA={time,tile}
        #  NETCDF_DIM_tile_DEF={3,6}
        #  NETCDF_DIM_tile_VALUES={1,2,3}
        #  NETCDF_DIM_time_DEF={12,6}
        #  NETCDF_DIM_time_VALUES={1,32,60,91,121,152,182,213,244,274,305,335}

        # open file and get basic info
        gdal.PushErrorHandler('CPLQuietErrorHandler')
        ds = gdal.Open(uri)
        gdal.PopErrorHandler()
        if ds is None:
            return
        wkt = ds.GetProjection()
        md = ds.GetMetadata()
        ds = None
        if md is None:
            return

        # update CRS selectors
        projectCrs = self.iface.mapCanvas().mapRenderer().destinationCrs()
        self.ui.cboCrs.setItemText(
            1,
            self.tr("Project") + " (%s, %s)" %
            (projectCrs.description(), projectCrs.authid()))

        if not wkt or not self.layerCrs.createFromWkt(wkt):
            self.layerCrs = QgsCoordinateReferenceSystem()
        if debug > 0:
            print('wkt: ' + wkt + ' layer desc:' + self.layerCrs.description())

        # if layer has valid crs, use that, if not use selected crs
        if self.layerCrs.description():
            self.ui.cboCrs.setItemText(
                0,
                self.tr("Layer") + " (%s, %s)" %
                (self.layerCrs.description(), self.layerCrs.authid()))
            self.ui.cboCrs.setCurrentIndex(0)
        else:
            self.ui.cboCrs.setItemText(0, self.tr("Layer (None)"))
            if self.selectedCrs.description():
                self.ui.cboCrs.setItemText(
                    2,
                    self.tr("Selected") + " (%s, %s)" %
                    (self.selectedCrs.description(), self.selectedCrs.authid())
                )
            else:
                self.ui.cboCrs.setItemText(2, self.tr("Selected (None)"))
            self.ui.cboCrs.setCurrentIndex(2)

        ds = None

        # iterate over all md items looking for dim info
        for key in sorted(md.iterkeys()):
            if key.startswith('NETCDF_DIM_'):
                line = "%s=%s" % (key, md[key])
                m = re.search('^(NETCDF_DIM_.+)={(.+)}', line)
                if m is not None:
                    dim_map[m.group(1)] = m.group(2)

        if not 'NETCDF_DIM_EXTRA' in dim_map:
            self.warning()
            return

        tok = dim_map['NETCDF_DIM_EXTRA']
        if tok is not None:
            for dim in tok.split(','):
                self.dim_names.append(dim)
                tok2 = dim_map.get('NETCDF_DIM_' + dim + '_VALUES')
                self.dim_values[dim] = []
                if tok2 is not None:
                    for s in tok2.split(','):
                        self.dim_values[dim].append(num(s))
                tok2 = dim_map.get('NETCDF_DIM_' + dim + '_DEF')
                self.dim_def[dim] = []
                if tok2 is not None:
                    for s in tok2.split(','):
                        self.dim_def[dim].append(num(s))

        # remove any dims which have only 1 element
        dim_names = self.dim_names
        self.dim_names = []
        for dim in dim_names:
            if self.dim_def[dim][0] <= 1:
                del self.dim_values[dim]
                del self.dim_def[dim]
            else:
                self.dim_names.append(dim)

        # transform time dimensions - currently requires netcdftime from python-netcdf4
        if has_netcdftime:
            for dim in dim_names:
                #dim+"#standard_name" in md and md[dim+"#standard_name"] == "time":
                if dim in self.dim_values:
                    if dim + "#units" in md:
                        timestr = md[dim + "#units"]
                        units = timestr.split()[0].lower()
                        if units in _units:
                            try:
                                dates = num2date(self.dim_values[dim],
                                                 units=timestr)
                            except ValueError:
                                continue
                            self.dim_values2[dim] = []
                            only_days = True
                            for date in dates:
                                val = date.isoformat(
                                    " "
                                )  # equivalent to strftime("%Y-%m-%d %H:%M:%S")
                                if not val.endswith(" 00:00:00"):
                                    only_days = False
                                self.dim_values2[dim].append(val)
                            if only_days:
                                for i in range(0, len(self.dim_values2[dim])):
                                    self.dim_values2[dim][
                                        i] = self.dim_values2[dim][i][0:10]

        if debug > 1:
            print(str(dim_map))
            print(str(self.dim_names))
            print(str(self.dim_def))
            print(str(self.dim_values))
            print(str(self.dim_values2))

        # update UI
        self.ui.pbnDim1.setEnabled(False)
        self.ui.pbnDim2.setEnabled(False)

        if len(self.dim_names) > 0:
            dim = self.dim_names[0]
            self.ui.lblDim1.setText(dim)
            menu = MyMenu()
            action = QAction(self.tr('all/none'), menu)
            action.setCheckable(True)
            menu.addAction(action)
            for i in range(0, len(self.dim_values[dim])):
                self.dim2Count = self.dim2Count + 1
                value = self.dim_values2[dim][
                    i] if dim in self.dim_values2 else self.dim_values[dim][i]
                action = QAction(str(value), menu)
                action.setCheckable(True)
                menu.addAction(action)
            self.ui.pbnDim1.setMenu(menu)
            QObject.connect(self.ui.pbnDim1.menu(),
                            SIGNAL("triggered(QAction *)"),
                            self.on_pbnDimx_triggered)
            # click first element of each dim
            if len(menu.actions()) > 1:
                menu.actions()[1].setChecked(True)
            self.ui.pbnDim1.setEnabled(True)

        if len(self.dim_names) > 1:
            dim = self.dim_names[1]
            self.ui.lblDim2.setText(dim)
            menu = MyMenu()
            action = QAction(self.tr('all/none'), menu)
            action.setCheckable(True)
            menu.addAction(action)
            for i in range(0, len(self.dim_values[dim])):
                self.dim2Count = self.dim2Count + 1
                value = self.dim_values[dim][i]
                action = QAction(str(value), menu)
                action.setCheckable(True)
                menu.addAction(action)
            self.ui.pbnDim2.setMenu(menu)
            QObject.connect(self.ui.pbnDim2.menu(),
                            SIGNAL("triggered(QAction *)"),
                            self.on_pbnDimx_triggered)
            # click first element of each dim
            if len(menu.actions()) > 1:
                menu.actions()[1].setChecked(True)
            self.ui.pbnDim2.setEnabled(True)

        # make sure we found something, if not notify user
        if len(self.dim_names) == 0:
            self.warning2()
        self.updateURI()
        self.updateDims()

    def updateDims(self):
        # TODO minimize calls to this fct
        if debug > 0:
            print('updateDims')
        self.updateDimsMulti()

    def updateDimsMulti(self):
        # update multi-band selection
        self.ui.leBandSelection.clear()
        if self.ui.pbnDim1.menu() is None and self.ui.pbnDim2.menu() is None:
            return
        sel1 = []
        i = 0
        actions = [] if self.ui.pbnDim1.menu(
        ) is None else self.ui.pbnDim1.menu().actions()
        for action in actions:
            if action.text() != self.tr('all/none'):
                if action.isChecked():
                    sel1.append(i)
                i = i + 1
        sel2 = []
        i = 0
        actions = [] if self.ui.pbnDim2.menu(
        ) is None else self.ui.pbnDim2.menu().actions()
        for action in actions:
            if action.text() != self.tr('all/none'):
                if action.isChecked():
                    sel2.append(i)
                i = i + 1

        sel_str = ''
        for dim1val in sel1:
            if self.ui.pbnDim2.menu() is None:
                band = dim1val + 1
                self.dim_band[band] = [dim1val + 1]
                sel_str = '%s%d ' % (sel_str, band)
            else:
                for dim2val in sel2:
                    band = self.bandNo(dim1val, dim2val)
                    self.dim_band[band] = [dim1val + 1, dim2val + 1]
                    sel_str = '%s%d ' % (sel_str, band)

        self.ui.leBandSelection.setText(sel_str)

    def bandNo(self, dim1val, dim2val):
        band = 0
        if dim2val > -1:
            band += dim2val + 1
        if dim1val > -1:
            if len(self.dim_def) > 0 and len(self.dim_names) > 0:
                band += (dim1val) * int(self.dim_def[self.dim_names[1]][0])
        return band

    def updateURI(self):
        if debug > 0:
            print('updateURI')
        # update URI
        fileInfo = QFileInfo(self.ui.leFileName.text())
        uri = 'NETCDF:"%s":%s' % (fileInfo.fileName(),
                                  self.ui.cboVars.currentText())
        self.ui.leURI.setText(uri)

    def on_pbnDimx_triggered(self, action):
        if action in self.ui.pbnDim1.menu().actions():
            pbn = self.ui.pbnDim1
        elif action in self.ui.pbnDim2.menu().actions():
            pbn = self.ui.pbnDim2
        else:
            return
        # 'all/none' action selects all/none
        if action.text() == self.tr('all/none'):
            pbn.blockSignals(True)
            for act in pbn.menu().actions():
                if act.text() != self.tr('all/none'):
                    act.setChecked(action.isChecked())
            pbn.blockSignals(False)

        # update selection
        self.updateDims()

    def on_pbnCrs_pressed(self):
        selector = QgsGenericProjectionSelector(self)
        selector.setMessage()
        if self.layerCrs.description():
            selector.setSelectedCrsId(self.layerCrs.srsid())
        elif self.selectedCrs.description():
            selector.setSelectedCrsId(self.selectedCrs.srsid())
        if selector.exec_():
            self.selectedCrs.createFromId(
                selector.selectedCrsId(),
                QgsCoordinateReferenceSystem.InternalCrsId)
            self.ui.cboCrs.setCurrentIndex(2)

        if self.selectedCrs.description():
            self.ui.cboCrs.setItemText(
                2,
                self.tr("Selected") + " (%s, %s)" %
                (self.selectedCrs.description(), self.selectedCrs.authid()))
        else:
            self.ui.cboCrs.setItemText(2, self.tr("Selected (None)"))