def check(self):
        """
        Perform some checks prior to trying to run

        :return: None
        """

        # check there is at least a 1d_nwk line layer to use
        if not self.getInputs('lines'):
            QMessageBox.critical(self, "Integrity Tool",
                                 "No Network Line(s) input.")
            return
        # check all input layers exist in the workspace
        inputTypes = ['lines', 'points', 'tables']
        for inputType in inputTypes:
            for input in self.getInputs(inputType, bReturnName=True):
                if tuflowqgis_find_layer(input) is None:
                    QMessageBox.critical(
                        self, "Integrity Tool",
                        "Layer Does Not Exist In Workspace: {0}".format(input))
                    return
        # check dem layer exists in the workspace
        if self.gbDem.isChecked():
            if tuflowqgis_find_layer(self.cboDem.currentText()) is None:
                QMessageBox.critical(
                    self, "Integrity Tool",
                    "DEM Layer Does Not Exist In Workspace: {0}".format(
                        self.cboDem.currentText()))
                return
        # check all layers are correct type
        for inputType in inputTypes:
            for layer in self.getInputs(inputType):
                if inputType == 'lines' or inputType == 'points':
                    if not is1dNetwork(layer):
                        QMessageBox.critical(
                            self, "Integrity Tool",
                            "Layer Is Not a 1d_nwk Type: {0}".format(
                                layer.name()))
                        return
                else:  # tables
                    if not is1dTable(layer):
                        QMessageBox.critical(
                            self, "Integrity Tool",
                            "Layer Is Not a 1d_ta Type: {0}".format(
                                layer.name()))
                        return

        self.run()
Ejemplo n.º 2
0
    def checkAreaInput(self, e=None, b=None) -> None:
        """

        :param e: QEvent
        :param b: bool isPointDescriptor
        :return: None
        """

        # remove previous messages
        for flag in self.flags[:]:
            if flag[0] is self.verticalLayout_23 or flag[
                    0] is self.horizontalLayout_6:  # input flag
                layout = flag[0]
                widget = flag[1]
                msg = flag[2]
                self.removeWidget(layout, widget, msg)

        isPointDescriptor = b
        if isPointDescriptor is None:
            isPointDescriptor = self.isPointDescriptor()

        # input area - required for point descriptors
        if isPointDescriptor:
            if self.rbUserArea.isChecked():
                if self.sbArea.value() <= 0:
                    msg = "Area Must Be Greater Than Zero For Point Descriptors"
                    label = self.createLabel(msg)
                    self.horizontalLayout_6.insertWidget(
                        self.horizontalLayout_6.count() - 1, label)
                    self.flags.append((self.horizontalLayout_6, label, msg))
            else:
                if self.cboInputGIS.currentText() == '-None-':
                    msg = "No Input GIS Catchment File Specified"
                    label = self.createLabel(msg)
                    self.verticalLayout_23.addWidget(label)
                    self.flags.append((self.verticalLayout_23, label, msg))
                elif tuflowqgis_find_layer(
                        self.cboInputGIS.currentText()) is None:
                    msg = "Input GIS Catchment File Not in Workspace"
                    label = self.createLabel(msg)
                    self.verticalLayout_23.addWidget(label)
                    self.flags.append((self.verticalLayout_23, label, msg))
                elif tuflowqgis_find_layer(self.cboInputGIS.currentText(
                )).geometryType() != QgsWkbTypes.PolygonGeometry:
                    msg = "Can Only Calculate Area From Region GIS Layer"
                    label = self.createLabel(msg)
                    self.verticalLayout_23.addWidget(label)
                    self.flags.append((self.verticalLayout_23, label, msg))
	def updateActiveMeshLayers(self):
		"""
		Updates the list of selected 2D results.
		
		:return: bool -> True for successful, False for unsuccessful
		"""
		
		self.activeMeshLayers = []
		openResults = self.tuView.OpenResults  # QListWidget
		
		for r in range(openResults.count()):
			item = openResults.item(r)
			
			# find selected layer
			layer = tuflowqgis_find_layer(item.text())
			if layer is not None:
				if layer.type() == 3:
					if item.isSelected():
						self.activeMeshLayers.append(layer)
					else:
						rs = layer.rendererSettings()
						rs.setActiveScalarDataset(QgsMeshDatasetIndex(-1, -1))
						layer.setRendererSettings(rs)
						rs.setActiveVectorDataset(QgsMeshDatasetIndex(-1, -1))
						layer.setRendererSettings(rs)
		
		return True
	def loadOpenMeshLayers(self, **kwargs):
		"""
		Checks the workspace for already open mesh layers and adds datasets to mesh and loads into interface.
		
		:return: bool -> True for successful, False for unsuccessful
		"""

		layer = kwargs['layer'] if 'layer' in kwargs.keys() else None
		
		if layer:
			meshLayers = [layer]
		else:
			meshLayers = findAllMeshLyrs()
		
		for ml in meshLayers:
			layer = tuflowqgis_find_layer(ml)
			if layer is not None:
				
				if layer.dataProvider().datasetGroupCount() == 0:
					return
				elif layer.dataProvider().datasetGroupCount() > 0:
					self.getResultMetaData(ml, layer)
					self.tuView.OpenResults.addItem(ml)
				
				layer.dataProvider().datasetGroupsAdded.connect(self.datasetGroupsAdded)
    def resultTypeDoubleClicked(self, event):
        """
		Event triggered when a result type is double clicked. Open properties dialog if a mesh layer result type.
		
		:param event: dict -> 'parent': parent DataSetTreeNode
		                      'item': clicked DataSetTreeNode
		:return:
		"""

        #self.doubleClickEvent = True

        # what happens if there is more than one active mesh layer
        if len(self.tuResults.tuResults2D.activeMeshLayers) > 1:
            self.meshDialog = tuflowqgis_meshSelection_dialog(
                self.iface, self.tuResults.tuResults2D.activeMeshLayers)
            self.meshDialog.exec_()
            if self.meshDialog.selectedMesh is None:
                return False
            else:
                meshLayer = tuflowqgis_find_layer(self.meshDialog.selectedMesh)
        else:
            meshLayer = self.tuResults.tuResults2D.activeMeshLayers[0]

        if event is not None:
            if event['parent'].ds_name == 'Map Outputs':
                self.iface.showLayerProperties(meshLayer)
        else:  # context menu
            if self.tuContextMenu.resultTypeContextItem.parentItem.ds_name == 'Map Outputs':
                self.iface.showLayerProperties(meshLayer)

        return True
    def populateInputs(self):
        """
        Populate available vector shp layers for the input comboboxes

        :return: void
        """

        # comboboxes
        lineCbos = [self.cboInputLines, self.cboInputTables]
        pointCbos = [self.cboInputPoints]

        # clear comboboxes
        for cbo in lineCbos:
            cbo.clear()
        for cbo in pointCbos:
            cbo.clear()

        # vector layers
        vectors = findAllVectorLyrs()

        # add vector layers to comboboxe if appropriate geometry type
        for vector in vectors:
            layer = tuflowqgis_find_layer(vector)
            if layer is not None:
                if layer.geometryType() == QgsWkbTypes.LineGeometry:
                    for cbo in lineCbos:
                        cbo.addItem(vector)
                elif layer.geometryType() == QgsWkbTypes.PointGeometry:
                    for cbo in pointCbos:
                        cbo.addItem(vector)
	def updateActiveMeshLayers(self):
		"""
		Updates the list of selected 2D results.
		
		:return: bool -> True for successful, False for unsuccessful
		"""
		
		self.activeMeshLayers = []
		openResults = self.tuView.OpenResults  # QListWidget
		
		for r in range(openResults.count()):
			item = openResults.item(r)
			
			# find selected layer
			layer = tuflowqgis_find_layer(item.text())
			if layer is not None:
				if isinstance(layer, QgsMeshLayer):
					if item.isSelected():
						self.activeMeshLayers.append(layer)
					else:
						rs = layer.rendererSettings()
						rs.setActiveScalarDataset(QgsMeshDatasetIndex(-1, -1))
						layer.setRendererSettings(rs)
						rs.setActiveVectorDataset(QgsMeshDatasetIndex(-1, -1))
						layer.setRendererSettings(rs)
		
		return True
	def loadOpenMeshLayers(self, **kwargs):
		"""
		Checks the workspace for already open mesh layers and adds datasets to mesh and loads into interface.
		
		:return: bool -> True for successful, False for unsuccessful
		"""

		layer = kwargs['layer'] if 'layer' in kwargs.keys() else None
		
		if layer:
			meshLayers = [layer]
		else:
			meshLayers = findAllMeshLyrs()
		
		for ml in meshLayers:
			layer = tuflowqgis_find_layer(ml)
			if layer is not None:
				
				if layer.dataProvider().datasetGroupCount() == 0:
					return
				elif layer.dataProvider().datasetGroupCount() > 0:
					self.getResultMetaData(ml, layer)
					self.tuView.OpenResults.addItem(ml)
				
				layer.dataProvider().datasetGroupsAdded.connect(self.datasetGroupsAdded)
	def resultTypeDoubleClicked(self, event):
		"""
		Event triggered when a result type is double clicked. Open properties dialog if a mesh layer result type.
		
		:param event: dict -> 'parent': parent DataSetTreeNode
		                      'item': clicked DataSetTreeNode
		:return:
		"""
		
		self.doubleClickEvent = True
		
		# what happens if there is more than one active mesh layer
		if len(self.tuResults.tuResults2D.activeMeshLayers) > 1:
			self.meshDialog = tuflowqgis_meshSelection_dialog(self.iface, self.tuResults.tuResults2D.activeMeshLayers)
			self.meshDialog.exec_()
			if self.meshDialog.selectedMesh is None:
				return False
			else:
				meshLayer = tuflowqgis_find_layer(self.meshDialog.selectedMesh)
		else:
			meshLayer = self.tuResults.tuResults2D.activeMeshLayers[0]
		
		if event is not None:
			if event['parent'].ds_name == 'Map Outputs':
				self.iface.showLayerProperties(meshLayer)
		else:  # context menu
			if self.tuContextMenu.resultTypeContextItem.parentItem.ds_name == 'Map Outputs':
				self.iface.showLayerProperties(meshLayer)
		
		return True
Ejemplo n.º 10
0
    def processActiveResults(self, call_type):
        """Saves active mesh layers to project"""

        openResults = self.tuView.OpenResults

        if call_type == 'save':
            selectedResults = []
            results = []
            for i in range(openResults.count()):
                item = openResults.item(i)
                results.append(item.text())
                if item.isSelected():
                    selectedResults.append(item.text())
            # get the result order
            allResults = ''
            for i, result in enumerate(results):
                if i == 0:
                    allResults += result
                else:
                    allResults += '~~{0}'.format(result)
            self.project.writeEntry("TUVIEW", "allresults", allResults)
            # get the selected results
            activeResults = ''
            for i, result in enumerate(selectedResults):
                if i == 0:
                    activeResults += result
                else:
                    activeResults += '~~{0}'.format(result)
            self.project.writeEntry("TUVIEW", "activeresults", activeResults)
        else:  # load
            allResults = self.project.readEntry("TUVIEW", 'allresults')[0]
            if allResults:
                allResults = allResults.split('~~')
            activeResults = self.project.readEntry("TUVIEW",
                                                   "activeresults")[0]
            if activeResults:
                activeResults = activeResults.split('~~')
            # first fix the order
            if allResults:
                openResults.clear()
                for res in allResults:
                    if res in self.tuView.tuResults.results:
                        openResults.addItem(res)
            # then enforce selection
            for i in range(openResults.count()):
                item = openResults.item(i)
                if item.text() in activeResults:
                    item.setSelected(True)
                else:
                    item.setSelected(False)
            self.tuView.tuResults.tuResults2D.activeMeshLayers.clear()
            if activeResults:
                for result in activeResults:
                    layer = tuflowqgis_find_layer(result)
                    if layer is not None:
                        self.tuView.tuResults.tuResults2D.activeMeshLayers.append(
                            layer)
	def processActiveResults(self, call_type):
		"""Saves active mesh layers to project"""
		
		openResults = self.tuView.OpenResults
		
		if call_type == 'save':
			selectedResults = []
			results = []
			for i in range(openResults.count()):
				item = openResults.item(i)
				results.append(item.text())
				if item.isSelected():
					selectedResults.append(item.text())
			# get the result order
			allResults = ''
			for i, result in enumerate(results):
				if i == 0:
					allResults += result
				else:
					allResults += '~~{0}'.format(result)
			self.project.writeEntry("TUVIEW", "allresults", allResults)
			# get the selected results
			activeResults = ''
			for i, result in enumerate(selectedResults):
				if i == 0:
					activeResults += result
				else:
					activeResults += '~~{0}'.format(result)
			self.project.writeEntry("TUVIEW", "activeresults", activeResults)
		else:  # load
			allResults = self.project.readEntry("TUVIEW", 'allresults')[0]
			if allResults:
				allResults = allResults.split('~~')
			activeResults = self.project.readEntry("TUVIEW", "activeresults")[0]
			if activeResults:
				activeResults = activeResults.split('~~')
			# first fix the order
			if allResults:
				openResults.clear()
				for res in allResults:
					if res in self.tuView.tuResults.results:
						openResults.addItem(res)
			# then enforce selection
			for i in range(openResults.count()):
				item = openResults.item(i)
				if item.text() in activeResults:
					item.setSelected(True)
				else:
					item.setSelected(False)
			self.tuView.tuResults.tuResults2D.activeMeshLayers.clear()
			if activeResults:
				for result in activeResults:
					layer = tuflowqgis_find_layer(result)
					if layer is not None:
						self.tuView.tuResults.tuResults2D.activeMeshLayers.append(layer)
    def updateTimeUnits(self):
        # turn off x axis freezing on time series plot
        self.tuView.tuPlot.tuPlotToolbar.viewToolbarTimeSeries.freezeXAxisAction.setChecked(
            False)
        self.tuView.tuPlot.tuPlotToolbar.viewToolbarTimeSeries.freezeXYAxisAction.setChecked(
            False)

        meshLayers = findAllMeshLyrs()
        for ml in meshLayers:
            layer = tuflowqgis_find_layer(ml)
            self.tuResults2D.getResultMetaData(ml, layer)
        self.updateResultTypes()
Ejemplo n.º 13
0
    def populateCboFields(self) -> None:
        """
        Add field names to combobox
        
        :return: None
        """

        self.cboFields.clear()

        layer = tuflowqgis_find_layer(self.cboInputGIS.currentText())
        if layer is not None:
            self.cboFields.addItems(layer.fields().names())
Ejemplo n.º 14
0
    def getInputs(self, inputType, bReturnName=False):
        """
        Get a list of the input types

        :param inputType: str
        :param returnNameL
        :return: list -> QgsMapLayer
        """

        inputs = []

        if inputType == 'lines':
            for i in range(self.lwLines.count()):
                item = self.lwLines.item(i)
                itemText = item.text()
                if bReturnName:  # append just the text name
                    inputs.append(itemText)
                else:  # append the QgsVectorLayer
                    layer = tuflowqgis_find_layer(itemText)
                    inputs.append(layer)
        elif inputType == 'points':
            for i in range(self.lwPoints.count()):
                item = self.lwPoints.item(i)
                itemText = item.text()
                if bReturnName:  # append just the text name
                    inputs.append(itemText)
                else:  # append the QgsVectorLayer
                    layer = tuflowqgis_find_layer(itemText)
                    inputs.append(layer)
        elif inputType == 'tables':
            for i in range(self.lwTables.count()):
                item = self.lwTables.item(i)
                itemText = item.text()
                if bReturnName:  # append just the text name
                    inputs.append(itemText)
                else:  # append the QgsVectorLayer
                    layer = tuflowqgis_find_layer(itemText)
                    inputs.append(layer)

        return inputs
Ejemplo n.º 15
0
    def populateCboFeatures(self) -> None:
        """
        Add feature IDs to combobox
    
        :return: None
        """

        self.cboFeatures.clear()

        layer = tuflowqgis_find_layer(self.cboInputGIS.currentText())
        if layer is not None:
            iField = self.cboFields.currentIndex()
            if iField > -1:
                atts = [str(f.attribute(iField)) for f in layer.getFeatures()]
                self.cboFeatures.addItems(atts)
	def datasetGroupsAdded(self):
		"""
		Re-indexes results because a new dataset (xmdf or dat) has been added through layer properties and not through
		the plugin.
		
		:return:
		"""

		meshLayers = findAllMeshLyrs()
		for ml in meshLayers:
			layer = tuflowqgis_find_layer(ml)
			if layer is not None:
				if layer.dataProvider().datasetGroupCount() == 0:
					return
				elif layer.dataProvider().datasetGroupCount() > 0:
					self.getResultMetaData(ml, layer)
					self.tuView.tuResults.updateResultTypes()
	def datasetGroupsAdded(self):
		"""
		Re-indexes results because a new dataset (xmdf or dat) has been added through layer properties and not through
		the plugin.
		
		:return:
		"""

		meshLayers = findAllMeshLyrs()
		for ml in meshLayers:
			layer = tuflowqgis_find_layer(ml)
			if layer is not None:
				if layer.dataProvider().datasetGroupCount() == 0:
					return
				elif layer.dataProvider().datasetGroupCount() > 0:
					self.getResultMetaData(ml, layer)
					self.tuView.tuResults.updateResultTypes()
Ejemplo n.º 18
0
    def runContinuityTool(self):
        """
        
        :return:
        """

        # Get inputs
        # input dem
        if self.gbDem.isChecked():
            dem = tuflowqgis_find_layer(self.cboDem.currentText())
        else:
            dem = None
        # input vector layers
        inputLines = self.getInputs('lines')
        inputPoints = self.getInputs('points')
        inputTables = self.getInputs('tables')

        # run data collectors
        self.runDataCollectors(inputLines,
                               inputPoints,
                               inputTables,
                               dem,
                               tool='Continuity Tool')
        self.outputLyr = None

        # user limits
        limitAngle = self.sbContinuityAngle.value()
        limitCover = self.sbContinuityCover.value()
        limitArea = self.sbContinuityArea.value()

        # user checks
        checkArea = self.cbContinuityArea.isChecked()
        checkInvert = self.cbContinuityInverts.isChecked()
        checkAngle = self.cbContinuityAngle.isChecked()
        checkCover = self.cbContinuityCover.isChecked()

        # continuity tool
        self.continuityTool = ContinuityTool(self.iface,
                                             self.dataCollectorLines,
                                             self.outputLyr, limitAngle,
                                             limitCover, limitArea, checkArea,
                                             checkAngle, checkInvert,
                                             checkCover)
        self.outputLyr = self.continuityTool.outputLyr
    def layersRemoved(self, removedLayers):
        """
		Triggered when layers are removed from the project. Will check if they are mesh layers and will remove from ui
		if they are.
		
		:param removedLayers: list -> QgsMapLayer
		:return: bool -> True for successful, False for unsuccessful
		"""

        for rlayer in removedLayers:
            layer = tuflowqgis_find_layer(rlayer, search_type='layerId')
            if layer is not None and isinstance(layer, QgsMeshLayer):
                for i in reversed(range(self.OpenResults.count())):
                    item = self.OpenResults.item(i)
                    itemName = item.text()
                    if itemName == layer.name():
                        self.tuResults.tuResults2D.removeResults([itemName])

        self.resultsChanged('force refresh')

        return True
	def layersRemoved(self, removedLayers):
		"""
		Triggered when layers are removed from the project. Will check if they are mesh layers and will remove from ui
		if they are.
		
		:param removedLayers: list -> QgsMapLayer
		:return: bool -> True for successful, False for unsuccessful
		"""

		for rlayer in removedLayers:
			layer = tuflowqgis_find_layer(rlayer, search_type='layerId')
			if layer is not None and layer.type() == 3:
				for i in reversed(range(self.OpenResults.count())):
					item = self.OpenResults.item(i)
					itemName = item.text()
					if itemName == layer.name():
						self.tuResults.tuResults2D.removeResults([itemName])

		self.resultsChanged('force refresh')
				
		return True
Ejemplo n.º 21
0
    def run(self) -> None:
        """
        Run the tool
        Collects inputs and passes to engine.py for processing
        
        :return: None
        """

        # collect inputs - initialise with actual values where can
        # otherwise some dummy values
        inputs = {
            'descriptor': self.leInputXML.text(),
            'location': Refh2.England if self.rbEngland.isChecked() else Refh2.Scotland,
            'area': 0,
            'return periods': [],
            'duration': None,
            'timestep': None,
            'season': Refh2.Winter if self.rbWinter.isChecked() else Refh2.Summer,
            'do output rainfall': True if self.gbOutRainfall.isChecked() else False,
            'do output hydrograph': True if self.gbOutHydrograph.isChecked() else False,
            'output data': [],
            'output hydrograph type': Refh2.Urban if self.rbUrban.isChecked() else Refh2.Rural,
            'output gis': None,
            'output file': self.leOutfile.text() if self.leOutfile.text() else \
                '{0}.csv'.format(os.path.splitext(self.leInputXML.text())[0]),
            'catchment name': None,
            'inflow name': 'Inflow',
            'rainfall name': 'Rainfall',
            'gis feature': None,
            'crs': None,
            'gis geometry': None,
            'zero padding': Refh2.AutoPad,
            'number zero padding': 3,
        }

        # populate rest with real values
        # inflow / rainfall names
        layer = tuflowqgis_find_layer(self.cboInputGIS.currentText())
        if self.cboInputGIS.currentText() and layer is not None:
            #layer = tuflowqgis_find_layer(self.cboInputGIS.currentText())
            #if layer is not None:
            inputs['gis geometry'] = layer.wkbType()
            crs = layer.sourceCrs()
            layerUnits = crs.mapUnits()
            inputs['crs'] = crs

            fid = self.cboFeatures.currentIndex()
            fids = {x.id(): x for x in layer.getFeatures()}
            feat = fids[fid]
            inputs['catchment name'] = '{0}'.format(
                feat.attribute(self.cboFields.currentIndex()))
            if inputs['do output rainfall'] and inputs['do output hydrograph']:
                inputs['inflow name'] = '{0}_inflow'.format(
                    feat.attribute(self.cboFields.currentIndex()))
                inputs['rainfall name'] = '{0}_rf'.format(
                    feat.attribute(self.cboFields.currentIndex()))
            else:
                inputs['inflow name'] = '{0}'.format(
                    feat.attribute(self.cboFields.currentIndex()))
                inputs['rainfall name'] = '{0}'.format(
                    feat.attribute(self.cboFields.currentIndex()))
        else:
            if self.gbBoundaryName.isChecked() and self.leBoundaryName.text():
                bname = self.leBoundaryName.text()
                if inputs['do output rainfall'] and inputs[
                        'do output hydrograph']:
                    inputs['inflow name'] = '{0}_inflow'.format(bname)
                    inputs['rainfall name'] = '{0}_rf'.format(bname)
                else:
                    inputs['inflow name'] = bname
                    inputs['rainfall name'] = bname

        # area
        if self.rbUserArea.isChecked():
            area = self.sbArea.value()
        else:
            area = feat.geometry().area()
            if layerUnits == QgsUnitTypes.DistanceMeters:
                area = area / 1000 / 1000
            elif layerUnits == QgsUnitTypes.DistanceCentimeters:
                area = area / 100000 / 100000
            elif layerUnits == QgsUnitTypes.DistanceMillimeters:
                area = area / 1000000 / 1000000
            elif layerUnits == QgsUnitTypes.DistanceFeet:
                area = area / 3.28084 / 3.28084 / 1000 / 1000
            elif layerUnits == QgsUnitTypes.DistanceNauticalMiles:
                area = area * 1852 * 1852 / 1000 / 1000
            elif layerUnits == QgsUnitTypes.DistanceYards:
                area = area / 1.09361 / 1.09361 / 1000 / 1000
            elif layerUnits == QgsUnitTypes.DistanceMiles:
                area = area * 1609.34 * 1609.34 / 1000 / 1000
            elif layerUnits == QgsUnitTypes.DistanceDegrees:
                # convert to meters
                centroid = feat.geometry().centroid()
                x = centroid.asPoint()[0]
                epsg = self.getCartesian(x)
                parameters = {
                    'INPUT': layer,
                    'TARGET_CRS': epsg,
                    'OUTPUT': 'memory:Reprojected'
                }
                reproject = processing.run("qgis:reprojectlayer", parameters)
                layer_reproject = reproject['OUTPUT']
                fids_reproject = {
                    x.id(): x
                    for x in layer_reproject.getFeatures()
                }
                feat_reproject = fids_reproject[fid]
                area = feat_reproject.geometry().area() / 1000 / 1000
            else:  # assume meters
                area = area / 1000 / 1000
        if area <= 0:
            area = 0.001
        inputs['area'] = area

        # return periods
        rps = []
        aris = [1, 2, 5, 10, 30, 50, 75, 100, 200, 1000]
        for ari in aris:
            cb = eval("self.cb{0:04d}y".format(ari))
            if cb.isChecked():
                rps.append(ari)
        for i in range(self.lwRP.count()):
            rps.append(int(self.lwRP.item(i).text().strip('year').strip()))
        inputs['return periods'] = rps

        # duration
        durText = self.leDuration.text()
        if durText != '::':
            inputs['duration'] = convertFormattedTimeToFromattedTime(durText)

        # timestep
        tsText = self.leTimestep.text()
        if tsText != '::':
            inputs['timestep'] = convertFormattedTimeToFromattedTime(tsText)

        # output data
        outdata = []
        if self.gbOutRainfall.isChecked():
            if self.rbGrossRainfall.isChecked():
                outdata.append(Refh2.GrossRainfall)
            else:
                outdata.append(Refh2.NetRainfall)
        if self.gbOutHydrograph.isChecked():
            if self.rbDirectRunoff.isChecked():
                outdata.append(Refh2.DirectRunoff)
            elif self.rbBaseFlow.isChecked():
                outdata.append(Refh2.BaseFlow)
            else:
                outdata.append(Refh2.TotalRunoff)
        inputs['output data'] = outdata

        # output GIS
        outGIS = []
        if self.gbOutRainfall.isChecked() and self.gbRainToGis.isChecked():
            inputs['gis feature'] = feat
            if self.rb2dRf.isChecked():
                outGIS.append(Refh2.RF)
            else:
                outGIS.append(Refh2.SA_RF)
        if self.gbOutHydrograph.isChecked() and self.gbHydToGis.isChecked():
            inputs['gis feature'] = feat
            if self.rb2dBc.isChecked():
                outGIS.append(Refh2.BC_2d)
            elif self.rb2dSa.isChecked():
                outGIS.append(Refh2.SA)
            else:
                outGIS.append(Refh2.BC_1d)
        if outGIS:
            inputs['output gis'] = outGIS

        # output zero padding
        if self.rbNoPad.isChecked():
            inputs['zero padding'] = Refh2.NoPad
        elif self.rbSetPad.isChecked():
            inputs['zero padding'] = Refh2.UserPad
            inputs['number zero padding'] = self.sbPadNo.value()

        # outfile - make sure output directory exists or can be created
        dir = os.path.dirname(inputs['output file'])
        if not makeDir(dir):
            QMessageBox.critical(
                self, "ReFH2 to TUFLOW",
                "Unexpected Error with Output File Location: "
                "Double Check Directory")
            return
        # make sure not locked for editing
        if os.path.exists(inputs['output file']):
            try:
                fo = open(inputs['output file'], 'a')
                fo.close()
            except PermissionError:
                QMessageBox.critical(
                    self, "ReFH2 to TUFLOW",
                    "Output File Locked:\n{0}".format(inputs['output file']))
                return
        # rainmodel - only 2013 available in this tool for now but can add 1999 later if needed
        rainModel = '2013'
        inputs['rain model'] = rainModel

        # setup run process on a separate thread
        # so that an infinite progress bar can be used
        self.thread = QThread()
        self.refh2 = Refh2(inputs)
        self.refh2.moveToThread(self.thread)
        self.refh2.locatingExe.connect(self.findingExe)
        self.refh2.refh2Start.connect(self.refh2Started)
        self.refh2.tuflowProcessingStart.connect(self.tuflowProcessingStarted)
        self.refh2.finished.connect(self.refh2Finished)
        self.thread.started.connect(self.refh2.run)
        self.thread.start()

        self.progressBar.setRange(0, 0)
        self.progressBar.setValue(0)
    def qgisDisconnect(self, completely_remove=False):
        """
		Disconnect signals


		:return:
		"""

        if self.connected or completely_remove:

            # time
            try:
                self.cboTime.currentIndexChanged.disconnect()
            except:
                pass
            try:
                self.sliderTime.valueChanged.disconnect()
            except:
                pass
            try:
                self.btnFirst.clicked.disconnect()
            except:
                pass
            try:
                self.btnPrev.clicked.disconnect()
            except:
                pass
            try:
                self.btnNext.clicked.disconnect()
            except:
                pass
            try:
                self.btnLast.clicked.disconnect()
            except:
                pass
            try:
                self.btnTimePlay.clicked.disconnect()
            except:
                pass
            try:
                self.btn2dLock.clicked.disconnect()
            except:
                pass

            # results
            try:
                self.OpenResults.itemSelectionChanged.disconnect()
            except:
                pass
            try:
                self.OpenResults.itemClicked.disconnect()
            except:
                pass

            # result types
            try:
                self.OpenResultTypes.secondAxisClicked.disconnect()
            except:
                pass
            try:
                self.OpenResultTypes.maxClicked.disconnect()
            except:
                pass
            try:
                self.OpenResultTypes.doubleClicked.disconnect()
            except:
                pass
            try:
                self.OpenResultTypes.leftClicked.disconnect()
            except:
                pass

            # Plotting buttons
            try:
                self.cbShowCurrentTime.clicked.disconnect()
            except:
                pass
            try:
                self.tuPlot.tuPlotToolbar.fluxSecAxisButton.released.disconnect(
                )
            except:
                pass

            # switching between plots
            try:
                self.tabWidget.currentChanged.disconnect()
            except:
                pass

            # interface
            try:
                self.iface.currentLayerChanged.disconnect(
                    self.currentLayerChanged)
            except:
                pass

            # project
            try:
                self.project.layersAdded.disconnect(self.layersAdded)
            except:
                pass
            if completely_remove:
                try:
                    self.project.layersWillBeRemoved.disconnect(
                        self.layersRemoved)
                except:
                    pass
                try:
                    self.project.projectSaved.disconnect(self.projectSaved)
                except:
                    pass
            try:
                self.project.cleared.disconnect(self.projectCleared)
            except:
                pass

            # layer
            if self.selectionChangeConnected or completely_remove:
                try:
                    self.currentLayer.selectionChanged.disconnect(
                        self.selectionChanged)
                except:
                    pass
                try:
                    self.selectionChangeConnected = False
                except:
                    pass

            if completely_remove:
                meshLayers = findAllMeshLyrs()
                for ml in meshLayers:
                    layer = tuflowqgis_find_layer(ml)
                    try:
                        layer.dataProvider().datasetGroupsAdded.disconnect(
                            self.datasetGroupsAdded)
                    except:
                        pass

            self.connected = False
Ejemplo n.º 23
0
    def runFlowTraceTool(self):
        """
        
        :return:
        """

        # Get inputs
        # input dem
        if self.gbDem.isChecked():
            dem = tuflowqgis_find_layer(self.cboDem.currentText())
        else:
            dem = None
        # input vector layers
        inputLines = self.getInputs('lines')
        inputPoints = self.getInputs('points')
        inputTables = self.getInputs('tables')

        # starting features
        startLocs = []
        for lyr in inputLines:
            selFeats = lyr.selectedFeatures()
            for f in selFeats:
                fid = f.id()
                loc = (lyr.name(), fid)
                startLocs.append(loc)

        if not startLocs:
            QMessageBox.critical(
                self, "Flow Trace",
                "Need to select at least one feature to start the flow trace from"
            )
            return

        # run data collectors
        self.runFlowTraceCollectors(inputLines,
                                    inputPoints,
                                    inputTables,
                                    dem,
                                    startLocs,
                                    tool='Flow Trace Tool')
        self.outputLyr = None

        # user limits
        limitAngle = self.sbFlowTraceAngle.value()
        limitCover = self.sbFlowTraceCover.value()
        limitArea = self.sbFlowTraceArea.value()

        # user checks
        checkArea = self.cbFlowTraceArea.isChecked()
        checkInvert = self.cbFlowTraceInverts.isChecked()
        checkAngle = self.cbFlowTraceAngle.isChecked()
        checkCover = self.cbFlowTraceCover.isChecked()

        # flow trace tool
        self.flowTraceTool = FlowTraceTool(self.iface, self.dataCollectorLines,
                                           self.outputLyr, limitAngle,
                                           limitCover, limitArea, checkArea,
                                           checkAngle, checkInvert, checkCover,
                                           self.dataCollectorPoints)
        self.outputLyr = self.flowTraceTool.outputLyr

        if self.cbFlowTraceLongPlots.isChecked():
            self.dotCount = 0
            self.message = "Generating Long Profiles"
            self.runStatus.setText(self.message)
            self.progressBar.setValue(0)
            self.progressBar.setRange(0, 0)
            self.plot = FlowTracePlot(self.iface, self.flowTraceTool)
            self.plot.finished.connect(self.showPlot)
            self.plot.updated.connect(self.updateStatusBar)
            self.plot.updateMessage.connect(self.updateMessage)
	def importResults(self, inFileNames):
		"""
		Imports function that opens result mesh layer

		:param inFileNames: list -> str - full path to mesh result file
		:return: bool -> True for successful, False for unsuccessful
		"""

		# disconnect incoming signals for load step
		skipConnect = False
		try:
			self.tuView.project.layersAdded.disconnect(self.tuView.layersAdded)
		except:
			skipConnect = True
			pass
		meshLayers = findAllMeshLyrs()
		for ml in meshLayers:
			layer = tuflowqgis_find_layer(ml)
			try:
				layer.dataProvider().datasetGroupsAdded.disconnect(self.datasetGroupsAdded)
			except:
				pass

		for j, f in enumerate(inFileNames):

			# Load Mesh
			if type(inFileNames) is dict:  # being loaded in from a sup file
				m = inFileNames[f]['mesh']
				mLayer, name, preExisting = self.loadMeshLayer(m, name=f)
			else:
				mLayer, name, preExisting = self.loadMeshLayer(f)
			if mLayer is None or name is None:
				if not skipConnect:
					self.tuView.project.layersAdded.connect(self.tuView.layersAdded)
				return False
			
			# Load Results
			if os.path.splitext(f)[1].lower() != '.nc':
				if type(inFileNames) is dict:  # being loaded in from a sup file
					datasets = inFileNames[f]['datasets']
					for d in datasets:
						l = self.loadDataGroup(d, mLayer, preExisting)
				else:
					loaded = self.loadDataGroup(f, mLayer, preExisting)
			#res = {'path': f}
			#self.results2d[mLayer.name()] = res
			
			# Open layer in map
			self.tuView.project.addMapLayer(mLayer)
			name = mLayer.name()
			mLayer.nameChanged.connect(lambda: self.layerNameChanged(mLayer, name, mLayer.name()))  # if name is changed can capture this in indexing
			
			rs = mLayer.rendererSettings()
			rsMesh = rs.nativeMeshSettings()
			rsMesh.setEnabled(self.tuView.tuOptions.showGrid)
			rs.setNativeMeshSettings(rsMesh)
			mLayer.setRendererSettings(rs)
			#mLayer.repaintRequested.connect(lambda: self.tuView.repaintRequested(mLayer))
			
			# Index results
			ext = os.path.splitext(f)[-1]  # added because .dat scalar and vector need to be combined
			index = self.getResultMetaData(name, mLayer, ext)
			if not index:
				if not skipConnect:
					self.tuView.project.layersAdded.connect(self.tuView.layersAdded)
				return False
			
			# add to result list widget
			names = []
			for i in range(self.tuView.OpenResults.count()):
				if self.tuView.OpenResults.item(i).text() not in names:
					names.append(self.tuView.OpenResults.item(i).text())
			if name not in names:
				self.tuView.OpenResults.addItem(name)  # add to widget
			k = self.tuView.OpenResults.findItems(name, Qt.MatchRecursive)[0]
			k.setSelected(True)
			updated = self.updateActiveMeshLayers()  # update list of active mesh layers
			if not updated:
				if not skipConnect:
					self.tuView.project.layersAdded.connect(self.tuView.layersAdded)
				return False
			self.tuView.resultChangeSignalCount = 0  # reset signal count back to 0
		
		# connect load signals
		if not skipConnect:
			self.tuView.project.layersAdded.connect(self.tuView.layersAdded)
		meshLayers = findAllMeshLyrs()
		for ml in meshLayers:
			layer = tuflowqgis_find_layer(ml)
			layer.dataProvider().datasetGroupsAdded.connect(self.datasetGroupsAdded)

			
		return True
Ejemplo n.º 25
0
    def addItem(self, cbo, lw, geometryType):
        """
        Adds specified input item to the list widget.

        :param cbo: QComboBox
        :param lw: QListWidget
        :param geometryType: QgsWkbTypes
        :return: void
        """

        # get existing items
        addedItems = []
        for i in range(lw.count()):
            item = lw.item(i)
            itemText = item.text()
            addedItems.append(itemText)

        # first check if there is any text there
        if cbo.currentText():
            # replace path separators so they are consistent with os
            text = cbo.currentText().replace("/", os.sep)

            # check if there are multiple items to add
            items = text.split(';;')

            # loop through items and add to list widget
            for item in items:
                if item.count(os.sep) > 0:
                    # file path so need to add to workspace
                    # and check geometry type
                    if os.path.splitext(item)[1].lower() == '.shp':
                        try:
                            name = os.path.basename(os.path.splitext(item)[0])
                            # check if already open in workspace
                            layer = tuflowqgis_find_layer(name)
                            if layer is not None:
                                # already open
                                if layer.geometryType() == geometryType:
                                    if name not in addedItems:
                                        lw.addItem(name)
                                        addedItems.append(name)
                                        if lw == self.lwLines:
                                            self.inputLineAdded.emit(layer)
                                else:
                                    QMessageBox.critical(
                                        self, "1D Integrity Tool",
                                        "Geometry type does not match required input type"
                                    )
                            else:
                                # need to add to workspace
                                self.iface.addVectorLayer(item, name, "ogr")
                                layer = tuflowqgis_find_layer(name)
                                if layer is not None:
                                    if layer.geometryType() == geometryType:
                                        if name not in addedItems:
                                            lw.addItem(name)
                                            addedItems.append(name)
                                            if lw == self.lwLines:
                                                self.inputLineAdded.emit(layer)
                                    else:
                                        QgsProject.instance().removeMapLayer(
                                            layer)
                                        QMessageBox.critical(
                                            self, "1D Integrity Tool",
                                            "Geometry type does not match required input type"
                                        )
                                else:
                                    QMessageBox.critical(
                                        self, "1D Integrity Tool",
                                        "Unexpected error")
                        except:
                            QMessageBox.critical(
                                self, "1D Integrity Tool",
                                "Error importing layer into QGIS")
                    else:
                        QMessageBox.critical(
                            self, "1D Integrity Tool",
                            "Input layer needs to be a shp file")
                else:
                    # trying to add an already open layer
                    layer = tuflowqgis_find_layer(item)
                    if layer is not None:
                        if layer.geometryType() == geometryType:
                            if item not in addedItems:
                                lw.addItem(item)
                                addedItems.append(item)
                                if lw == self.lwLines:
                                    self.inputLineAdded.emit(layer)
                        else:
                            QMessageBox.critical(
                                self, "1D Integrity Tool",
                                "Geometry type does not match required input type"
                            )
Ejemplo n.º 26
0
    def processMeshStyles(self, call_type):
        """Project settings for scalar and vector mesh styles."""

        results = self.tuView.tuResults.results
        menuFunctions = self.tuView.tuMenuBar.tuMenuFunctions
        results2D = self.tuView.tuResults.tuResults2D

        if call_type == 'save':
            for result, rtypeDict in results.items():
                # result -> 'M03_5m_001'
                # rtype -> 'Depth' or 'point_ts'
                for rtype, timeDict in rtypeDict.items():
                    if '_ts' not in rtype and '_lp' not in rtype:
                        if type(
                                timeDict
                        ) is dict:  # make sure we're looking at 2d results
                            for time, items in timeDict.items(
                            ):  # just do first timestep
                                # time -> '0.0000'
                                # items -> ( timestep, type, QgsMeshDatasetIndex )
                                dtype = items[
                                    1]  # data type e.g. scalar or vector
                                mindex = items[2]  # QgsMeshDatasetIndex
                                style = None
                                if dtype == 1:  # scalar
                                    style = menuFunctions.saveDefaultStyleScalar(
                                        'color map',
                                        mesh_index=mindex,
                                        result=result,
                                        save_type='project')
                                    if style is not None:
                                        rtypeFormatted = rtype.replace(
                                            '/', '_')
                                        rtypeFormatted = rtypeFormatted.replace(
                                            ' ', '_')
                                        self.project.writeEntry(
                                            "TUVIEW",
                                            "scalarstyle_{0}_{1}".format(
                                                result, rtypeFormatted), style)
                                elif dtype == 2:  # vector
                                    style = menuFunctions.saveDefaultStyleVector(
                                        mesh_index=mindex,
                                        save_type='project',
                                        result=result)
                                    for key, item in style.items():
                                        if key == 'color':
                                            item = item.name()
                                        rtypeFormatted = rtype.replace(
                                            '/', '_')
                                        rtypeFormatted = rtypeFormatted.replace(
                                            ' ', '_')
                                        keyFormatted = key.replace(' ', '_')
                                        self.project.writeEntry(
                                            "TUVIEW",
                                            "vectorstyle_{0}_{1}_{2}".format(
                                                result, rtypeFormatted,
                                                keyFormatted),
                                            "{0}".format(item))

                                break  # only do first timestep
        else:  # load
            for result, rtypeDict in results.items():
                # result -> 'M03_5m_001'
                # rtype -> 'Depth' or 'point_ts'
                layer = tuflowqgis_find_layer(result)
                for rtype, timeDict in rtypeDict.items():
                    if '_ts' not in rtype and '_lp' not in rtype:
                        if type(
                                timeDict
                        ) is dict:  # make sure we're looking at 2d results
                            for time, items in timeDict.items(
                            ):  # just do first timestep
                                # time -> '0.0000'
                                # items -> ( timestep, type, QgsMeshDatasetIndex )
                                rtypeFormatted = rtype.replace('/', '_')
                                rtypeFormatted = rtypeFormatted.replace(
                                    ' ', '_')
                                style = self.project.readEntry(
                                    "TUVIEW", "scalarstyle_{0}_{1}".format(
                                        result, rtypeFormatted))[0]
                                dtype = items[
                                    1]  # data type e.g. scalar or vector
                                mindex = items[2]  # QgsMeshDatasetIndex
                                gindex = mindex.group()  # int group index
                                if dtype == 1:
                                    results2D.applyScalarRenderSettings(
                                        layer,
                                        gindex,
                                        style,
                                        'map',
                                        save_type='project')
                                elif dtype == 2:
                                    propertyDict = {}
                                    propertyList = [
                                        'arrow head length ratio',
                                        'arrow head width ratio', 'color',
                                        'filter max', 'filter min',
                                        'fixed shaft length', 'line width',
                                        'max shaft length', 'min shaft length',
                                        'scale factor', 'shaft length method'
                                    ]
                                    for property in propertyList:
                                        propertyFormatted = property.replace(
                                            ' ', '_')
                                        value = self.project.readEntry(
                                            "TUVIEW",
                                            "vectorstyle_{0}_{1}_{2}".format(
                                                result, rtypeFormatted,
                                                propertyFormatted))[0]
                                        if value == '':
                                            continue
                                        if property == 'color':
                                            item = QColor(value)
                                        elif property == 'shaft length method':
                                            item = int(value)
                                        else:
                                            item = float(value)
                                        propertyDict[property] = item
                                    results2D.applyVectorRenderSettings(
                                        layer, gindex, propertyDict)
                                break
	def loadMeshLayer(self, fpath, **kwargs):
		"""
		Load the mesh layer i.e. .xmdf

		:param fpath: str
		:return: QgsMeshLayer
		:return: str
		"""

		# deal with kwargs
		name = kwargs['name'] if 'name' in kwargs else None

		# Parse out file names
		basepath, fext = os.path.splitext(fpath)
		basename = os.path.basename(basepath)
		dirname = os.path.dirname(basepath)
		
		# does mesh layer already exist in workspace
		layer = tuflowqgis_find_layer(basename)
		if layer is not None:
			return layer, basename, True
		# TUFLOW FV 2dm is named differently so also check provided name does not exist
		if name is not None:
			layer_alternative = tuflowqgis_find_layer(name)
			if layer_alternative is not None:
				return layer_alternative, name, True
		
		if fext.lower() == '.xmdf' or fext.lower() == '.dat' or fext.lower() == '.2dm':
			mesh = '{0}.2dm'.format(basepath)
		elif fext.lower() == '.nc':
			mesh = fpath
		else:
			QMessageBox.information(self.iface.mainWindow(), "TUFLOW Viewer",
			                        "Must select a .xmdf .dat .sup .nc or .2dm file type")
			return None, None, False

		basename_copy = basename
		while not os.path.exists(mesh):  # put in for res_to_res results e.g. M01_5m_002_V_va.xmdf (velocity angle)
			components = basename_copy.split('_')
			components.pop()
			if not components:
				break
			basename_copy = '_'.join(components)
			mesh = '{0}.2dm'.format(os.path.join(dirname, basename_copy))
		if not os.path.exists(mesh):
			# ask user for location
			inFileNames = QFileDialog.getOpenFileNames(self.tuView.iface.mainWindow(), 'Mesh file location', fpath,
			                                           "TUFLOW Mesh File (*.2dm)")
			if not inFileNames[0]:  # empty list
				return None, None, False
			else:
				if os.path.exists(inFileNames[0][0]):
					mesh = inFileNames[0][0]
				else:
					QMessageBox.information(self.iface, "TUFLOW Viewer", "Could not find mesh file")
					return None, None, False

			
		# Load mesh if layer does not exist already
		name = basename if name is None else name
		layer = QgsMeshLayer(mesh, name, 'mdal')
		if layer.isValid():
			if fext.lower() == '.nc':
				return layer, name, False
			else:
				prop = {}
				cellSize, wllVerticalOffset, origin, orientation, gridSize = getPropertiesFrom2dm(mesh)
				prop['cell size'] = cellSize
				prop['wll vertical offset'] = wllVerticalOffset
				prop['origin'] = origin
				prop['orientation'] = orientation
				prop['grid size'] = gridSize
				self.meshProperties[name] = prop
				self.tuView.tuOptions.resolution = cellSize
				return layer, name, False
		
		QMessageBox.information(self.iface.mainWindow(), "TUFLOW Viewer", "Could not load mesh file")
		return None, None, False
	def importResults(self, inFileNames):
		"""
		Imports function that opens result mesh layer

		:param inFileNames: list -> str - full path to mesh result file
		:return: bool -> True for successful, False for unsuccessful
		"""

		# disconnect incoming signals for load step
		self.tuView.project.layersAdded.disconnect(self.tuView.layersAdded)
		meshLayers = findAllMeshLyrs()
		for ml in meshLayers:
			layer = tuflowqgis_find_layer(ml)
			try:
				layer.dataProvider().datasetGroupsAdded.disconnect(self.datasetGroupsAdded)
			except:
				pass

		for j, f in enumerate(inFileNames):

			# Load Mesh
			if type(inFileNames) is dict:  # being loaded in from a sup file
				m = inFileNames[f]['mesh']
				mLayer, name, preExisting = self.loadMeshLayer(m, name=f)
			else:
				mLayer, name, preExisting = self.loadMeshLayer(f)
			if mLayer is None or name is None:
				self.tuView.project.layersAdded.connect(self.tuView.layersAdded)
				return False
			
			# Load Results
			if type(inFileNames) is dict:  # being loaded in from a sup file
				datasets = inFileNames[f]['datasets']
				for d in datasets:
					l = self.loadDataGroup(d, mLayer, preExisting)
			else:
				loaded = self.loadDataGroup(f, mLayer, preExisting)
			#res = {'path': f}
			#self.results2d[mLayer.name()] = res
			
			# Open layer in map
			self.tuView.project.addMapLayer(mLayer)
			name = mLayer.name()
			mLayer.nameChanged.connect(lambda: self.layerNameChanged(mLayer, name, mLayer.name()))  # if name is changed can capture this in indexing
			
			rs = mLayer.rendererSettings()
			rsMesh = rs.nativeMeshSettings()
			rsMesh.setEnabled(self.tuView.tuOptions.showGrid)
			rs.setNativeMeshSettings(rsMesh)
			mLayer.setRendererSettings(rs)
			#mLayer.repaintRequested.connect(lambda: self.tuView.repaintRequested(mLayer))
			
			# Index results
			ext = os.path.splitext(f)[-1]  # added because .dat scalar and vector need to be combined
			index = self.getResultMetaData(name, mLayer, ext)
			if not index:
				self.tuView.project.layersAdded.connect(self.tuView.layersAdded)
				return False
			
			# add to result list widget
			names = []
			for i in range(self.tuView.OpenResults.count()):
				if self.tuView.OpenResults.item(i).text() not in names:
					names.append(self.tuView.OpenResults.item(i).text())
			if name not in names:
				self.tuView.OpenResults.addItem(name)  # add to widget
			k = self.tuView.OpenResults.findItems(name, Qt.MatchRecursive)[0]
			k.setSelected(True)
			updated = self.updateActiveMeshLayers()  # update list of active mesh layers
			if not updated:
				self.tuView.project.layersAdded.connect(self.tuView.layersAdded)
				return False
			self.tuView.resultChangeSignalCount = 0  # reset signal count back to 0
		
		# connect load signals
		self.tuView.project.layersAdded.connect(self.tuView.layersAdded)
		meshLayers = findAllMeshLyrs()
		for ml in meshLayers:
			layer = tuflowqgis_find_layer(ml)
			layer.dataProvider().datasetGroupsAdded.connect(self.datasetGroupsAdded)

			
		return True
Ejemplo n.º 29
0
    def check(self) -> None:
        """
        Checks input for silly mistakes or omissions as best as can
        at this stage.

        If passes all checks, will start run function :)
        
        :return: None
        """

        # start with already found flags
        for flag in self.flags:
            msg = flag[2]
            QMessageBox.critical(self, "ReFH2 to TUFLOW", msg)
            return

        # input catchment descriptor / locator - required
        if not self.leInputXML.text():
            QMessageBox.critical(
                self, "ReFH2 to TUFLOW",
                "No Catchment Descriptor Input Locator File Specified")
            return
        if not os.path.exists(self.leInputXML.text()):
            QMessageBox.critical(
                self, "ReFH2 to TUFLOW",
                "Catchment Descriptor Input Locator File Does Not Exist")
            return

        # Return Period - at least one return period and must be between 1 and 1000 year inclusive
        rps = []
        aris = [1, 2, 5, 10, 30, 50, 75, 100, 200, 1000]
        for ari in aris:
            cb = eval("self.cb{0:04d}y".format(ari))
            if cb.isChecked():
                rps.append(ari)
        for i in range(self.lwRP.count()):
            rp = self.lwRP.item(i).text().strip('year').strip()
            if not 1 <= int(rp) <= 1000:
                QMessageBox.critical(self, "ReFH2 to TUFLOW",
                                     "Return Period Not Valid: {0}".format(rp))
                return
            else:
                rps.append(rp)
        if not rps:
            QMessageBox.critical(self, "ReFH2 to TUFLOW",
                                 "No Return Period(s) Selected")
            return

        # output
        if self.gbOutRainfall.isChecked() and self.gbRainToGis.isChecked():
            if not self.cboInputGIS.currentText() or not self.cboFields.currentText() \
                    or not self.cboFeatures.currentText():
                QMessageBox.critical(
                    self, "ReFH2 to TUFLOW",
                    "Must Specify Input GIS Layer to Output To TUFLOW GIS")
                return
            if self.rb2dRf.isChecked() and \
                    tuflowqgis_find_layer(self.cboInputGIS.currentText()).geometryType() != QgsWkbTypes.PolygonGeometry:
                QMessageBox.critical(
                    self, "ReFH2 to TUFLOW",
                    "Must Use Region GIS Layer to Output 2d_rf")
                return
            if self.rb2dSaRf.isChecked() and \
                    tuflowqgis_find_layer(self.cboInputGIS.currentText()).geometryType() != QgsWkbTypes.PolygonGeometry:
                QMessageBox.critical(
                    self, "ReFH2 to TUFLOW",
                    "Must Use Region GIS Layer to Output 2d_sa_rf")
                return
        if self.gbOutHydrograph.isChecked() and self.gbHydToGis.isChecked():
            if not self.cboInputGIS.currentText() or not self.cboFields.currentText() \
                    or not self.cboFeatures.currentText():
                QMessageBox.critical(
                    self, "ReFH2 to TUFLOW",
                    "Must Specify Input GIS Layer to Output To TUFLOW GIS")
                return
            if self.rb2dSa.isChecked() and \
                    tuflowqgis_find_layer(self.cboInputGIS.currentText()).geometryType() != QgsWkbTypes.PolygonGeometry:
                QMessageBox.critical(
                    self, "ReFH2 to TUFLOW",
                    "Must Use Region GIS Layer to Output 2d_sa")
                return
            if self.rb2dBc.isChecked() and \
                    tuflowqgis_find_layer(self.cboInputGIS.currentText()).geometryType() != QgsWkbTypes.LineGeometry:
                QMessageBox.critical(
                    self, "ReFH2 to TUFLOW",
                    "Must Use Line GIS Layer to Output 2d_bc")
                return
            if self.rb1dBc.isChecked() and \
                    tuflowqgis_find_layer(self.cboInputGIS.currentText()).geometryType() == QgsWkbTypes.LineGeometry:
                QMessageBox.critical(
                    self, "ReFH2 to TUFLOW",
                    "Cannot Use Line GIS Layer to Output 1d_bc")
                return
        if self.rbQgisArea.isChecked():
            # if using spherical coords, check it can be converted to cartesian
            layer = tuflowqgis_find_layer(self.cboInputGIS.currentText())
            crs = layer.sourceCrs()
            layerUnits = crs.mapUnits()
            if layerUnits == QgsUnitTypes.DistanceDegrees:
                fid = self.cboFeatures.currentIndex()
                fids = {x.id(): x for x in layer.getFeatures()}
                feat = fids[fid]
                x = feat.geometry().centroid().asPoint()[0]
                if self.getCartesian(x) is None:
                    QMessageBox.critical(
                        self, "ReFH2 to TUFLOW",
                        "Difficulty Converting Degrees to Meters... "
                        "Please Double Check Projection and Location"
                        "of Input GIS Layer and Workspace")
                    return

        self.run()
Ejemplo n.º 30
0
    def runSnappingTool(self):
        """
        
        :return:
        """

        # Get inputs
        # input dem
        if self.gbDem.isChecked():
            dem = tuflowqgis_find_layer(self.cboDem.currentText())
        else:
            dem = None
        # input vector layers
        inputLines = self.getInputs('lines')
        inputPoints = self.getInputs('points')
        inputTables = self.getInputs('tables')

        # run data collectors
        self.runDataCollectors(inputLines,
                               inputPoints,
                               inputTables,
                               dem,
                               tool='Snapping Tool')
        self.outputLyr = None

        # get exlusion radius
        exclRadius = self.sbExclRadius.value() if self.cbExclRadius.isChecked(
        ) else 99999

        # check snapping
        self.snappingToolLines = SnappingTool(
            iface=self.iface,
            dataCollector=self.dataCollectorLines,
            outputLyr=self.outputLyr,
            exclRadius=exclRadius,
            dataCollectorPoints=self.dataCollectorPoints)
        self.outputLyr = self.snappingToolLines.outputLyr
        if inputPoints:
            self.snappingToolPoints = SnappingTool(
                iface=self.iface,
                dataCollector=self.dataCollectorPoints,
                outputLyr=self.outputLyr,
                exclRadius=exclRadius,
                dataCollectorLines=self.dataCollectorLines)

        # auto snap
        if self.cbAutoSnap.isChecked():
            radius = self.sbAutoSnapSearchRadius.value()
            self.snappingToolLines.autoSnap(radius)
            for lyr in self.snappingToolLines.tmpLyrs:
                QgsProject.instance().addMapLayer(lyr)
            if inputPoints:
                self.snappingToolPoints.autoSnap(radius)
                for lyr in self.snappingToolPoints.tmpLyrs:
                    QgsProject.instance().addMapLayer(lyr)

            noAutoSnap = True
            if self.snappingToolLines.tmpLyrs:
                noAutoSnap = False
            if inputPoints:
                if self.snappingToolPoints.tmpLyrs:
                    noAutoSnap = False
            if noAutoSnap:
                QMessageBox.information(
                    self.iface.mainWindow(), "Integrity Tool",
                    "No auto snapping operations performed.")
	def loadMeshLayer(self, fpath, **kwargs):
		"""
		Load the mesh layer i.e. .xmdf

		:param fpath: str
		:return: QgsMeshLayer
		:return: str
		"""

		# deal with kwargs
		name = kwargs['name'] if 'name' in kwargs else None

		# Parse out file names
		basepath, fext = os.path.splitext(fpath)
		basename = os.path.basename(basepath)
		dirname = os.path.dirname(basepath)
		
		# does mesh layer already exist in workspace
		layer = tuflowqgis_find_layer(basename)
		if layer is not None:
			return layer, basename, True
		# TUFLOW FV 2dm is named differently so also check provided name does not exist
		if name is not None:
			layer_alternative = tuflowqgis_find_layer(name)
			if layer_alternative is not None:
				return layer_alternative, name, True
		
		if fext.lower() == '.xmdf' or fext.lower() == '.dat' or fext.lower() == '.2dm':
			mesh = '{0}.2dm'.format(basepath)
			basename_copy = basename
			while not os.path.exists(mesh):  # put in for res_to_res results e.g. M01_5m_002_V_va.xmdf (velocity angle)
				components = basename_copy.split('_')
				components.pop()
				if not components:
					break
				basename_copy = '_'.join(components)
				mesh = '{0}.2dm'.format(os.path.join(dirname, basename_copy))
			if not os.path.exists(mesh):
				# ask user for location
				inFileNames = QFileDialog.getOpenFileNames(self.tuView.iface.mainWindow(), 'Mesh file location', fpath,
				                                           "TUFLOW Mesh File (*.2dm)")
				if not inFileNames[0]:  # empty list
					return None, None, False
				else:
					if os.path.exists(inFileNames[0][0]):
						mesh = inFileNames[0][0]
					else:
						QMessageBox.information(self.iface, "TUFLOW Viewer", "Could not find mesh file")
						return None, None, False
		else:
			QMessageBox.information(self.iface.mainWindow(), "TUFLOW Viewer", "Must select a .xmdf .dat .sup or .2dm file type")
			return None, None, False
			
		# Load mesh if layer does not exist already
		name = basename if name is None else name
		layer = QgsMeshLayer(mesh, name, 'mdal')
		if layer.isValid():
			prop = {}
			cellSize, wllVerticalOffset, origin, orientation, gridSize = getPropertiesFrom2dm(mesh)
			prop['cell size'] = cellSize
			prop['wll vertical offset'] = wllVerticalOffset
			prop['origin'] = origin
			prop['orientation'] = orientation
			prop['grid size'] = gridSize
			self.meshProperties[name] = prop
			self.tuView.tuOptions.resolution = cellSize
			return layer, name, False
		
		QMessageBox.information(self.iface.mainWindow(), "TUFLOW Viewer", "Could not load mesh file")
		return None, None, False
	def run(self, preview):
		"""run tool"""
		
		self.tuView.qgisDisconnect()
		
		if not preview:
			self.buttonBox.setEnabled(False)  # disable button box so users know something is happening
			QApplication.setOverrideCursor(Qt.WaitCursor)
			
		# save plot settings so line colours won't vary over time
		self.tuView.tuPlot.setNewPlotProperties(0)
		self.tuView.tuPlot.setNewPlotProperties(1)
		
		# get page properties
		conv = 1 if self.cboUnits.currentText() == 'mm' else 25.4
		w = self.sbWidth.value() * conv
		h = self.sbHeight.value() * conv
		
		# set all results inactive
		for i in range(self.tuView.OpenResults.count()):
			item = self.tuView.OpenResults.item(i)
			item.setSelected(False)
		self.tuView.tuResults.tuResults2D.activeMeshLayers = []
		
		# Get Map Layout properties
		legendProp = {}
		if self.groupLegend.isChecked():
			legendProp['label'] = self.labelLegend.text()
			legendProp['font'] = self.fbtnLegend.currentFont()
			legendProp['font colour'] = self.colorLegendText.color()
			legendProp['background'] = self.cbLegendBackground.isChecked()
			legendProp['background color'] = self.colorLegendBackground.color()
			legendProp['frame'] = self.cbLegendFrame.isChecked()
			legendProp['frame color'] = self.colorLegendFrame.color()
			legendProp['position'] = self.cboPosLegend.currentIndex()
		scaleBarProp = {}
		if self.groupScaleBar.isChecked():
			scaleBarProp['font'] = self.fbtnScaleBar.currentFont()
			scaleBarProp['font color'] = self.colorScaleBarText.color()
			scaleBarProp['background'] = self.cbScaleBarBackground.isChecked()
			scaleBarProp['background color'] = self.colorScaleBarBackground.color()
			scaleBarProp['frame'] = self.cbScaleBarFrame.isChecked()
			scaleBarProp['frame color'] = self.colorScaleBarFrame.color()
			scaleBarProp['position'] = self.cboPosScaleBar.currentIndex()
		northArrowProp = {}
		if self.groupNorthArrow.isChecked():
			northArrowProp['background'] = self.cbNorthArrowBackground.isChecked()
			northArrowProp['background color'] = self.colorNorthArrowBackground.color()
			northArrowProp['frame'] = self.cbNorthArrowFrame.isChecked()
			northArrowProp['frame color'] = self.colorNorthArrowFrame.color()
			northArrowProp['position'] = self.cboPosNorthArrow.currentIndex()
		labelProp = {}
		if self.groupLabel.isChecked():
			#labelProp['label'] = self.labelInput.toPlainText()
			labelProp['font'] = self.fbtnLabel.currentFont()
			labelProp['font colour'] = self.colorLabelText.color()
			labelProp['background'] = self.cbLabelBackground.isChecked()
			labelProp['background color'] = self.colorLabelBackground.color()
			labelProp['frame'] = self.cbLabelFrame.isChecked()
			labelProp['frame color'] = self.colorLabelFrame.color()
			labelProp['position'] = self.cboPosLabel.currentIndex()
		layout = {}
		if self.radLayoutDefault.isChecked():
			layout['type'] = 'default'
			layout['file'] = None
			if self.groupLegend.isChecked():
				layout['legend'] = legendProp
			if self.groupScaleBar.isChecked():
				layout['scale bar'] = scaleBarProp
			if self.groupNorthArrow.isChecked():
				layout['north arrow'] = northArrowProp
		else:
			layout['type'] = 'file'
			layout['file'] = self.editTemplate.text()
		if self.groupLabel.isChecked():
			layout['title'] = labelProp
			
		# Get Plot Data
		if self.groupPlot.isChecked():
			plot = {}
			plotCount = 0
			for i in range(self.tablePlots.rowCount()):
				plotDict = {}
				plotDict['labels'] = self.tablePlots.cellWidget(i, 1).checkedItems()
				plotDict['type'] = self.tablePlots.cellWidget(i, 0).currentText()
				plotDict['position'] = self.tablePlots.cellWidget(i, 2).currentIndex()
				plotDict['properties'] = self.pbDialogs[self.tablePlots.cellWidget(i, 3)]
				plot[plotCount] = plotDict
				plotCount += 1
			if plot:
				layout['plots'] = plot
			graphics = {}
			for i in range(self.tableGraphics.rowCount()):
				cb = self.tableGraphics.item(i, 0)
				if cb.checkState() == Qt.Checked:
					graphicDict = {}
					label = self.tableGraphics.item(i, 0)
					graphic = self.label2graphic[label.text()]
					userLabel = self.tableGraphics.cellWidget(i, 1).text()
					position = self.tableGraphics.cellWidget(i, 2).currentText()
					font = self.rowNo2fntDialog[i]
					graphicDict['user label'] = userLabel
					graphicDict['position'] = position
					graphicDict['font'] = font.fntButton.currentFont()
					graphicDict['font colour'] = font.fntColor.color()
					graphicDict['background'] = font.cbBackground.isChecked()
					graphicDict['background color'] = font.backgroundColor.color()
					graphicDict['frame'] = font.cbFrame.isChecked()
					graphicDict['frame color'] = font.frameColor.color()
					if 'TS' in label.text():
						graphicDict['type'] = 'marker'
					elif 'CS' in label.text():
						graphicDict['type'] = 'rubberband profile'
					else:
						graphicDict['type'] = 'rubberband flow'
					graphics[graphic] = graphicDict
			if graphics:
				layout['graphics'] = graphics
		
		# Get Image Data
		if self.groupImages.isChecked():
			image = {}
			imageCount = 0
			for i in range(self.tableImages.rowCount()):
				imageDict = {
					'source': self.tableImages.cellWidget(i, 0).layout().itemAt(1).widget().text(),
					'position': self.tableImages.cellWidget(i, 1).currentIndex(),
					'properties': self.pbDialogsImage[self.tableImages.cellWidget(i, 2)]
				}
				image[imageCount] = imageDict
				imageCount += 1
			layout['images'] = image
			
		prog = lambda i, count: self.updateProgress(i, count)  # progress bar
		
		pageMargin = (self.sbPageMarginLeft.value(), self.sbPageMarginRight.value(),
		              self.sbPageMarginTop.value(), self.sbPageMarginBottom.value())
		# put collected data into dictionary for easy access later
		d = {'img_size': (w, h),
		     'extent': self.canvas.extent(),
		     'crs': self.canvas.mapSettings().destinationCrs(),
		     'layout': layout,
		     'dpi': self.sbDpi.value(),
		     'frame': self.cbPageFrame.isChecked(),
		     'frame color': self.colorPageFrame.color(),
		     'frame thickness': self.sbPageFrameThickness.value(),
		     'page margin': pageMargin
		     }
		
		count = self.tableMaps.rowCount()
		for i in range(count):
			d['map number'] = i
			prog(i, count)
			
			# outfile
			path = self.tableMaps.cellWidget(i, 4).layout().itemAt(1).widget().text()
			d['imgfile'] = path
			
			# result layer
			layer = self.tableMaps.cellWidget(i, 0).layout().itemAt(1).widget().currentText()
			if layer not in self.tuView.tuResults.results:
				imported = self.tuView.tuMenuBar.tuMenuFunctions.load2dResults(result_2D=[[layer]])
				if not imported:
					continue
				layer = tuflowqgis_find_layer(self.tuView.OpenResults.item(self.tuView.OpenResults.count() - 1).text())
				d['rendered'] = False
			else:
				layer = tuflowqgis_find_layer(layer)
				d['rendered'] = True
			self.tuView.tuResults.tuResults2D.activeMeshLayers = []
			self.tuView.tuResults.tuResults2D.activeMeshLayers.append(layer)
			d['layer'] = layer
			
			# get maplayers - only include the one mesh layer
			layerOrder = self.canvas.layers()
			layers = []
			for name, mapLayer in QgsProject.instance().mapLayers().items():
				if mapLayer.type() == 3:
					if mapLayer == layer:
						layers.append(mapLayer)
				else:
					layers.append(mapLayer)
			layersOrdered = []
			for l in layerOrder:
				if l in layers:
					layersOrdered.append(l)
			for l in layers:
				if l not in layersOrdered:
					layersOrdered.insert(0, l)
			d['layers'] = layersOrdered
			
			# uncheck unwanted mesh layers in layers panel
			legint = self.tuView.project.layerTreeRoot()
			# grab all nodes that are QgsMapLayers - get to node bed rock i.e. not a group
			nodes = []
			for item in legint.children():
				items = [item]
				while items:
					it = items[0]
					if it.children():
						items += it.children()
					else:
						nodes.append(it)
					items = items[1:]
			# now turn off all nodes that are mesh layers that are not the one we are interested in
			for node in nodes:
				# turn on node visibility for all items
				# so we can get the corresponding map layer
				# but record visibility status and turn off
				# again if it's not the mesh layer we're interested it
				if node.checkedLayers():
					visible = True
				else:
					visible = False
					node.setItemVisibilityChecked(True)
				ml = node.checkedLayers()[0] if node.checkedLayers() else False
				if ml:
					if ml.type() == 3:  # is a mesh layer
						if ml == layer:  # is the layer we're interested in
							node.setItemVisibilityChecked(True)
						else:  # is NOT the mesh layer we're interested in
							node.setItemVisibilityChecked(False)
					else:
						node.setItemVisibilityChecked(visible)
			
			# label text
			text = self.labelInput.toPlainText()
			result = layer.name()
			scalar = self.tableMaps.cellWidget(i, 1).currentText()
			vector = self.tableMaps.cellWidget(i, 2).currentText()
			time = self.tableMaps.cellWidget(i, 3).currentText()
			template = ''
			if self.cbSaveTemplates.isChecked():
				template = self.leTemplateOut.text()
			label = createText(text, result, scalar, vector, time, path, template, self.project, i + 1)
			if self.groupLabel.isChecked():
				d['layout']['title']['label'] = label
				
			# active scalar and vector index
			if time.lower() != 'max':
				time = time.split(':')
				time = float(time[0]) + float(time[1]) / 60 + float(time[2]) / 3600
				d['time'] = time
			else:
				d['time'] = -99999
				scalar += '/Maximums'
				vector += '/Maximums'
				time = 0.0
			scalarInd = -1
			vectorInd = -1
			for i in range(layer.dataProvider().datasetGroupCount()):
				if str(layer.dataProvider().datasetGroupMetadata(i).name()).lower() == scalar.lower():
					scalarInd = i
				if str(layer.dataProvider().datasetGroupMetadata(i).name()).lower() == vector.lower():
					vectorInd = i
			asd = QgsMeshDatasetIndex(-1, 0)
			for i in range(layer.dataProvider().datasetCount(scalarInd)):
				ind = QgsMeshDatasetIndex(scalarInd, i)
				if layer.dataProvider().datasetMetadata(ind).time() == time:
					asd = ind
			avd = QgsMeshDatasetIndex(-1, 0)
			for i in range(layer.dataProvider().datasetCount(vectorInd)):
				ind = QgsMeshDatasetIndex(vectorInd, i)
				if layer.dataProvider().datasetMetadata(ind).time() == time:
					avd = ind
			d['scalar index'] = asd
			d['vector index'] = avd
			
			for pb, dialog in self.pbDialogs.items():
				dialog.setDefaults(self, self.dialog2Plot[dialog][0].currentText(),
				                   self.dialog2Plot[dialog][1].checkedItems(), static=True)
			
			self.layout = makeMap(d, self.iface, prog, self, preview, i)
			
			if preview:
				self.iface.openLayoutDesigner(layout=self.layout)
				self.tuView.qgisConnect()
				return
			
			if self.cbSaveTemplates.isChecked():
				folder = self.leTemplateOut.text()
				name = os.path.splitext(os.path.basename(path))[0] + '.qpt'
				templateFile = os.path.join(folder, name)
				
			
		self.tuView.qgisConnect()
		QApplication.restoreOverrideCursor()
		self.updateProgress(0, 1)
		self.buttonBox.setEnabled(True)
		self.accept()
	def processMeshStyles(self, call_type):
		"""Project settings for scalar and vector mesh styles."""
		
		results = self.tuView.tuResults.results
		menuFunctions = self.tuView.tuMenuBar.tuMenuFunctions
		results2D = self.tuView.tuResults.tuResults2D
		
		if call_type == 'save':
			for result, rtypeDict in results.items():
				# result -> 'M03_5m_001'
				# rtype -> 'Depth' or 'point_ts'
				for rtype, timeDict in rtypeDict.items():
					if '_ts' not in rtype and '_lp' not in rtype:
						if type(timeDict) is dict:  # make sure we're looking at 2d results
							for time, items in timeDict.items():  # just do first timestep
								# time -> '0.0000'
								# items -> ( timestep, type, QgsMeshDatasetIndex )
								dtype = items[1]  # data type e.g. scalar or vector
								mindex = items[2]  # QgsMeshDatasetIndex
								style = None
								if dtype == 1:  # scalar
									style = menuFunctions.saveDefaultStyleScalar('color map', mesh_index=mindex,
									                                             result=result, save_type='project')
									if style is not None:
										rtypeFormatted = rtype.replace('/', '_')
										rtypeFormatted = rtypeFormatted.replace(' ', '_')
										self.project.writeEntry("TUVIEW",
										                        "scalarstyle_{0}_{1}".format(result, rtypeFormatted),
										                        style)
								elif dtype == 2:  # vector
									style = menuFunctions.saveDefaultStyleVector(mesh_index=mindex, save_type='project',
									                                             result=result)
									for key, item in style.items():
										if key == 'color':
											item = item.name()
										rtypeFormatted = rtype.replace('/', '_')
										rtypeFormatted = rtypeFormatted.replace(' ', '_')
										keyFormatted = key.replace(' ', '_')
										self.project.writeEntry("TUVIEW",
										                        "vectorstyle_{0}_{1}_{2}".format(
											                        result, rtypeFormatted, keyFormatted),
										                        "{0}".format(item))
								
								break  # only do first timestep
		else:  # load
			for result, rtypeDict in results.items():
				# result -> 'M03_5m_001'
				# rtype -> 'Depth' or 'point_ts'
				layer = tuflowqgis_find_layer(result)
				for rtype, timeDict in rtypeDict.items():
					if '_ts' not in rtype and '_lp' not in rtype:
						if type(timeDict) is dict:  # make sure we're looking at 2d results
							for time, items in timeDict.items():  # just do first timestep
								# time -> '0.0000'
								# items -> ( timestep, type, QgsMeshDatasetIndex )
								rtypeFormatted = rtype.replace('/', '_')
								rtypeFormatted = rtypeFormatted.replace(' ', '_')
								style = self.project.readEntry("TUVIEW",
								                               "scalarstyle_{0}_{1}".format(result, rtypeFormatted))[0]
								dtype = items[1]  # data type e.g. scalar or vector
								mindex = items[2]  # QgsMeshDatasetIndex
								gindex = mindex.group()  # int group index
								if dtype == 1:
									results2D.applyScalarRenderSettings(layer, gindex, style, 'map',
									                                    save_type='project')
								elif dtype == 2:
									propertyDict = {}
									propertyList = [
										'arrow head length ratio',
										'arrow head width ratio',
										'color',
										'filter max',
										'filter min',
										'fixed shaft length',
										'line width',
										'max shaft length',
										'min shaft length',
										'scale factor',
										'shaft length method'
									]
									for property in propertyList:
										propertyFormatted = property.replace(' ', '_')
										value = self.project.readEntry("TUVIEW",
										                               "vectorstyle_{0}_{1}_{2}".format(
											                               result, rtypeFormatted, propertyFormatted))[0]
										if value == '':
											continue
										if property == 'color':
											item = QColor(value)
										elif property == 'shaft length method':
											item = int(value)
										else:
											item = float(value)
										propertyDict[property] = item
									results2D.applyVectorRenderSettings(layer, gindex, propertyDict)
								break
	def updateTimeUnits(self):
		meshLayers = findAllMeshLyrs()
		for ml in meshLayers:
			layer = tuflowqgis_find_layer(ml)
			self.tuResults2D.getResultMetaData(ml, layer)
		self.updateResultTypes()