def __init__(self, pointLayer, iface): # processing.initialize() self.iface = iface self.com = Communicate(self.iface) self.pLayer = pointLayer self.PredictionLayer = "" self.VarianceLayer = ""
def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgisInterface """ # type: object # Save reference to the QGIS interface self.output_set = None self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) self.com = Communicate(self.iface) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'mainPlug_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&EggAGGIS') self.toolbar = self.iface.addToolBar(u'mainPlug') self.toolbar.setObjectName(u'mainPlug') # Do some C like shenanigans self.DialogStore = [None] * 15
def __init__(self, path, iface): """ Take in a file to work on, Initialize and work upon :param path: Path to file :type path: str :param iface: QGIS iface :type iface: iface """ self.iface = iface self.path = path self.com = Communicate(self.iface) try: self.csvFile = open(path, 'rb') except IOError: self.com.error(Bold="IOerror", String="Could not load given File", level=2) except BaseException: self.com.error( Bold="Unknown Error", String="An Unknown Error occured (See log for details", level=2) self.com.log( "IOPARSE Encountered an Unknown error attempting to initialize self.csvFile", level=2) self.Values = 0 self.ValueList = [] self.LayerList = []
def __init__(self, iface): """ The work horse of the NDVI calculations, named rasterManip due to it's older functions :param iface: The iface passed in from mainPlug """ self.iface = iface self.com = Communicate(self.iface)
def __init__(self): """ Initialize the File Import Class """ self.com = Communicate() self.filePath = '' self.fileInfo = None self.baseName = None self.rLayer = None
class ThreadDataInterp(Thread): def __init__(self, iface, rLayer): """ Process one Raster, returning the Dataset THIS IS DEPRECATED :param iface: QGIS Iface :param rLayer: rLayer object to Process """ Thread.__init__(self) self.iface = iface self.rLayer = rLayer self.com = Communicate(self.iface) self.FinishedDataset = [] self.FinishOrder = [] self.DataStore = [] self.rLayerX = rLayer.width() self.rLayerY = rLayer.height() self.ThreadArray = [] def ProcessrLayer(self): """ Setup a thread for each Y Value in rLayer TODO: Test to see if doing a thread per pixel would Speed things up or if Near Approximation would help :return: The final Stitched Dataset of rLayer (After being passed to ConvertToFinish) """ self.com.log("Producing Threads for Interpretation", 0) v = 0 for i in range(self.rLayerY): self.ThreadArray.append(InterpObj(iface=self.iface, rLayer=self.rLayer, DataStore=self.DataStore, Finishorder=self.FinishOrder, Yval=i)) v += 1 for i in self.ThreadArray: i.start() for i in self.ThreadArray: i.join(5) self.com.log("Threaded Interp Finished", 0) return self.ConvertToFinish() def ConvertToFinish(self): """ Restitch the Jumbled Dataset (Due to Concurrent Returns) :return: The ReStitched DataSet """ for idx, val in enumerate(self.FinishOrder): for i in self.DataStore[idx]: self.FinishedDataset.append(i) return self.FinishedDataset def run(self): return self.ProcessrLayer()
def __init__(self): """ Export a file as an ASCII tif """ self.com = Communicate() self.filePath = '' self.ExportX = 0 self.ExportY = 0 self.XLLCorner = 0 self.YLLCorner = 0 self.cellSize = 0 self.NoDataValue = -9999 self.DataSet = None
def __init__(self, pointLayer, iface): """ Setup the Interpolate Function :param pointLayer: The Layer to process :type pointLayer: QgsVectorLayer :param iface: QGIS iface :type iface: iface """ # processing.initialize() self.iface = iface self.com = Communicate(self.iface) self.pLayer = pointLayer self.PredictionLayer = "" self.VarianceLayer = ""
class FileImport: def __init__(self): """ Initialize the File Import Class """ self.com = Communicate() self.filePath = '' self.fileInfo = None self.baseName = None self.rLayer = None def file_input(self, path): """ Set the path and Setup the File to be used later :param path: Path to the file you wish to use :type path: str :return: None """ if path == '': self.com.log("FILE PATH EMPTY", 2) raise IOError self.filePath = path self.fileInfo = QFileInfo(self.filePath) self.baseName = self.fileInfo.baseName() # Ensure that this stays in as this is how the Raster is imported. self.check_file_type() def check_file_type(self): """ Validate the File type as a Valid Raster layer :return: None """ self.rLayer = QgsRasterLayer(self.filePath, self.baseName) if not self.rLayer.isValid(): self.rLayer = None self.com.log("Check File Type Error: Layer Invalid", 2) def get_rLayer(self): """ Get the rLayer :return: rLayer Obj """ return self.rLayer
def __init__(self, path, iface): self.iface = iface self.path = path self.com = Communicate(self.iface) try: self.csvFile = open(path, 'rb') except IOError: self.com.error( Bold="IOerror", String="Could not load given File", level=2) except: self.com.error( Bold="Unknown Error", String="An Unknown Error occured (See log for details", level=2) self.com.log( "IOPARSE Encountered an Unknown error attempting to initialize self.csvFile", level=2) self.Values = 0 self.ValueList = [] self.LayerList = []
def __init__(self, iface, rLayer): """ Process one Raster, returning the Dataset THIS IS DEPRECATED :param iface: QGIS Iface :param rLayer: rLayer object to Process """ Thread.__init__(self) self.iface = iface self.rLayer = rLayer self.com = Communicate(self.iface) self.FinishedDataset = [] self.FinishOrder = [] self.DataStore = [] self.rLayerX = rLayer.width() self.rLayerY = rLayer.height() self.ThreadArray = []
def __init__(self, iface, rLayer, DataStore, Finishorder, Yval): """ Interpret a row of the rLayer given based off the given Y-Value. :param iface: QGis Iface :param rLayer: rLayer Pointer :param DataStore: DataStore Pointer :param Finishorder: Finish Order Array pointer :param Yval: The Y row """ Thread.__init__(self) self.iface = iface self.com = Communicate(self.iface) self.rLayer = rLayer self.DataStore = DataStore self.Finishorder = Finishorder self.Yval = Yval self.a = RasterManip(iface=self.iface) self.internalData = []
class InterpObj(Thread): def __init__(self, iface, rLayer, DataStore, Finishorder, Yval): """ Interpret a row of the rLayer given based off the given Y-Value. :param iface: QGis Iface :param rLayer: rLayer Pointer :param DataStore: DataStore Pointer :param Finishorder: Finish Order Array pointer :param Yval: The Y row """ Thread.__init__(self) self.iface = iface self.com = Communicate(self.iface) self.rLayer = rLayer self.DataStore = DataStore self.Finishorder = Finishorder self.Yval = Yval self.a = RasterManip(iface=self.iface) self.internalData = [] def run(self): """ Grab the value of Every X pixel in the Y row on the Given rLayer :return: Appending The Value to a new Array within the Datastore array and The given Y value to the Finish order signaling it's time of completion """ for i in range(self.rLayer.width()): ret = self.a.return_dataset(i, -self.Yval, rLayer=self.rLayer) self.internalData.append(ret) self.DataStore.append(self.internalData) self.Finishorder.append(self.Yval) self.com.log("Interp OBJ completed Successfully", 0) return None
class mainPlug: """QGIS Plugin main body Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgisInterface """ # type: object # Save reference to the QGIS interface self.output_set = None self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) self.com = Communicate(self.iface) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'mainPlug_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&EggAGGIS') self.toolbar = self.iface.addToolBar(u'mainPlug') self.toolbar.setObjectName(u'mainPlug') # Do some C like shenanigans self.DialogStore = [None] * 15 # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('mainPlug', message) def add_action(self, icon_path, text, callback, store_val, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None, dialog=mainPlugDialog()): # type: (object, object, object, object, object, object, object,object, object, object, object) -> object """Add a toolbar icon to the toolbar. :param store_val: This value is the position to store the Dialog within the dialog list, Note that this position can and will interfere with standard operation if it is stored in an incorrect position at this time :type store_val: int :param dialog: The dialog you wish to Display to users :type dialog: function :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ # Create the dialog (after translation) and keep reference # noinspection PyTypeChecker self.DialogStore[store_val] = dialog icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/mainPlug\icon.png' about_path = ':/plugins/mainPlug\\about.png' """self.add_action( icon_path, store_val=0, text=self.tr(u'PlotData'), callback=self.run, parent=self.iface.mainWindow())""" """self.add_action( icon_path, store_val=1, text=self.tr(u'File_Import_Test'), callback=self.run_file_input, dialog=FileInputDialog() )""" self.add_action(about_path, store_val=2, text=self.tr(u'About'), callback=self.runabout, dialog=AboutDialog()) self.com.log("Add_action: About", 0) self.add_action(icon_path, store_val=3, text=self.tr(u'Calculate NDVI'), callback=self.run_calc_ndvi, dialog=ImportExportDialog()) self.com.log("Add_Action: Calculate NDVI", 0) self.add_action(icon_path, store_val=5, text=self.tr(u'Plot Soil data'), callback=self.run_SoilSample, dialog=CsvInputdialog()) self.add_action(icon_path, store_val=4, text=self.tr(u'Help'), callback=self.run_help, dialog=HelpDialog()) self.add_action(icon_path, store_val=6, text=self.tr(u'Krig'), callback=self.run_krig, dialog=KrigDialog()) def unload(self): """ Removes the plugin menu item and icon from QGIS GUI. """ for action in self.actions: self.iface.removePluginMenu(self.tr(u'&EggAGGIS'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar self.com.log("Unload Toolbar: Success", 0) def run(self): """ Run method that performs all the real work """ # show the dialog self.DialogStore[0].show() # Run the dialog event loop result = self.DialogStore[0].exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. pass def run_SoilSample(self): """ Run the CSV input dialog for Soil Sample input :return: """ from DataParse import IOParse diag = self.DialogStore[5] diag.show() result = diag.exec_() if result: result = diag.get_text() io_parse_result = IOParse(result, self.iface) io_parse_result.ReadFile() def run_file_input(self): """ Run file input :return: """ file_input = FileImport() diag = self.DialogStore[1] diag.show() result = diag.exec_() self.com.log("File Input Called", 0) if result: diag_result = diag.get_text() print("Result: ") print(diag_result) file_input.file_input(diag_result) self.com.log( "File Input Result: {0} | {1}".format(file_input.filePath, file_input.baseName), 0) self.iface.addRasterLayer(file_input.filePath, file_input.baseName) print(file_input.rLayer.renderer().type()) r_layer_x = file_input.rLayer.width() r_layer_y = file_input.rLayer.height() raster_manipulator = RasterManip(file_input.rLayer, self.iface) for i in range(r_layer_x): for j in range(r_layer_y): print i print j raster_manipulator.return_dataset(i, -j) # noinspection PyBroadException def run_calc_ndvi(self): # Warning to any maintainers, This is super spaghetti... I'm sorry, may the lord have mercy on your soul # If you don't want things to explode, the horses don't go # This is the best possible solution beyond doing if elif loops which would have been impossible # to maintain # If ye must pass I'll explain the best I can: """ Handle the NDVI Calc Window Sending the values to where they're needed and Exporting the final result to disk This entire bit is to determine the files inputted and their respective bands, be they NIR, RED, BLUE or GREEN Using the names of the files, Clever List usage and some Regex, We pass the rLayers (Raster Layer objects) in the correct order for the actual NDVI calculation in rasterManip, taking into account the Calculation type that the user has given :return: None :rtype: None """ nir_pattern = re.compile(r"NIR", re.IGNORECASE) red_pattern = re.compile(r"RED", re.IGNORECASE) blue_pattern = re.compile(r"BLUE", re.IGNORECASE) green_pattern = re.compile(r"GREEN", re.IGNORECASE) file_input_1 = FileImport() file_input_2 = FileImport() file_input_3 = FileImport() file_in_4 = FileImport() diag = self.DialogStore[3] diag.show() sort = [None, None, None] result = diag.exec_() raster_manipulator = RasterManip(iface=self.iface) if result: result = diag.get_text() result2 = diag.get_text2() result3 = diag.get_text3() file_input_1.file_input(result) self.com.log( "File Input Result {0} | {1}".format(file_input_1.filePath, file_input_1.baseName), 0) if result2 != '': file_input_2.file_input(result2) self.com.log( "File Input Result {0} | {1}".format( file_input_2.filePath, file_input_2.baseName), 0) if diag.get_calc() == "ENVDI" or diag.get_calc() == "EVI": if result3 != '': file_input_3.file_input(result3) self.com.log( "File Input Result {0} | {1}".format( file_input_3.filePath, file_input_3.baseName), 0) # Sort the Rasters based on name into their correct # positions sort_old = [file_input_1, file_input_2, file_input_3] for i in sort_old: if nir_pattern.search(i.baseName) is not None: self.com.log(str(sort), level=0) sort[0] = i self.com.log(str(sort), level=0) if green_pattern.search(i.baseName) is not None: self.com.log(str(sort), level=0) sort[1] = i self.com.log(str(sort), level=0) if blue_pattern.search(i.baseName) is not None: self.com.log(str(sort), level=0) sort[2] = i self.com.log(str(sort), level=0) if len(sort) != 3: self.com.error( String= "One of the Files is not labeled correctly, " "please Fix this and Rerun the program", level=2) return 0 else: if diag.get_calc() == "ENDVI": raster_manipulator.rastercalcmulti_ndvi( rLayer1=sort[0].rLayer, rLayer2=sort[1].rLayer, rLayer3=sort[2].rLayer, path=diag.exportText, calctype="ENVDI") elif diag.get_calc() == "EVI": raster_manipulator.rastercalcmulti_ndvi( rLayer1=sort[0].rLayer, rLayer2=sort[1].rLayer, rLayer3=sort[2].rLayer, path=diag.exportText, calctype="EVI") else: if diag.get_calc() == "NDVI": sort_old = [file_input_1, file_input_2] for i in sort_old: if nir_pattern.search(i.baseName) is not None: self.com.log(str(sort), level=0) sort[0] = i self.com.log(str(sort), level=0) if red_pattern.search(i.baseName) is not None: self.com.log(str(sort), level=0) sort[1] = i self.com.log(str(sort), level=0) if len(sort) != 3: self.com.error( String= "One of the Files is not labeled correctly," " please Fix this and Rerun the program", level=2) return 0 else: raster_manipulator.rastercalcmulti_ndvi( rLayer1=sort[0].rLayer, rLayer2=sort[1].rLayer, path=diag.exportText, calctype="NDVI") elif diag.get_calc() == "bNDVI": sort_old = [file_input_1, file_input_2] for i in sort_old: if nir_pattern.search(i.baseName) is not None: self.com.log(str(sort), level=0) sort[0] = i self.com.log(str(sort), level=0) if blue_pattern.search(i.baseName) is not None: self.com.log(str(sort), level=0) sort[1] = i self.com.log(str(sort), level=0) if len(sort) != 3: self.com.error( String= "One of the Files is not labeled correctly," " please Fix this and Rerun the program", level=2) return 0 else: raster_manipulator.rastercalcmulti_ndvi( rLayer1=sort[0].rLayer, rLayer2=sort[1].rLayer, path=diag.exportText, calctype="bNDVI") # This is fail-over For Single raster input else: if diag.get_calc() == "ENDVI": try: raster_manipulator.rastercalcmulti_ndvi( calctype="ENDVI", rLayer1=file_input_1.rLayer, rLayer2=file_input_1.rLayer, rLayer3=file_input_1.rLayer, r1Band=1, r2Band=2, r3Band=3, path=diag.exportText) except BaseException: self.com.error( String= "An Error Occurred upon Execution, Verify that the Input files are correct", level=2) elif diag.get_calc() == "bNDVI": try: raster_manipulator.rastercalcmulti_ndvi( calctype="bNDVI", rLayer1=file_input_1.rLayer, rLayer2=file_input_1.rLayer, r1Band=1, r2Band=2, path=diag.exportText) except BaseException: self.com.error( String= "An Error Occurred upon Execution, Verify that the Input files are correct", level=2) elif diag.get_calc() == "NDVI": try: raster_manipulator.rastercalcmulti_ndvi( calctype="NDVI", rLayer1=file_input_1.rLayer, rLayer2=file_input_1.rLayer, r1Band=1, r2Band=2, path=diag.exportText) except BaseException: self.com.error( String= "An Error Occurred upon Execution, Verify that the Input files are correct", level=2) elif diag.get_calc() == "EVI": try: raster_manipulator.rastercalcmulti_ndvi( calctype="EVI", path=diag.exportText, rLayer1=file_input_1.rLayer, rLayer2=file_input_1.rLayer, rLayer3=file_input_1.rLayer, r1Band=1, r2Band=2, r3Band=3) except BaseException: self.com.error( String= "An Error Occurred upon Execution, Verify that the Input files are correct", level=2) file_in_4.file_input(diag.exportText) self.Color(file_in_4, calcType=diag.get_calc()) else: self.com.error(String="NO RESULT", level=2) def Color(self, file_in, calcType=None): """ Color the Inbound file (Essentially the File we JUST exported) and display it to screen) :param file_in: The file that was just exported :type file_in: FileImport :return: TO SCREEN Rendered Image :rtype: None """ k = self.iface.addRasterLayer(file_in.filePath, file_in.baseName) stats = k.dataProvider().bandStatistics(1, QgsRasterBandStats.All, k.extent(), 0) minimum = stats.minimumValue maximum = stats.maximumValue self.com.log("Color func: [Min val: {0} | Max val: {1}".format( str(minimum), str(maximum)), level=0) ramp_shader = QgsColorRampShader() ramp_shader.setColorRampType(QgsColorRampShader.INTERPOLATED) if calcType is None: color_list = [ QgsColorRampShader.ColorRampItem(minimum, QColor(255, 0, 0)), QgsColorRampShader.ColorRampItem(0, QColor(255, 207, 74, 255)), QgsColorRampShader.ColorRampItem(maximum, QColor(0, 255, 0)) ] elif calcType == "EVI": color_list = [ QgsColorRampShader.ColorRampItem(-2, QColor(255, 0, 0)), QgsColorRampShader.ColorRampItem(0, QColor(255, 207, 74, 255)), QgsColorRampShader.ColorRampItem(2, QColor(0, 255, 0)) ] else: color_list = [ QgsColorRampShader.ColorRampItem(minimum, QColor(255, 0, 0)), QgsColorRampShader.ColorRampItem(0, QColor(255, 207, 74, 255)), QgsColorRampShader.ColorRampItem(maximum, QColor(0, 255, 0)) ] ramp_shader.setColorRampItemList(color_list) shader = QgsRasterShader() shader.setRasterShaderFunction(ramp_shader) renderer = QgsSingleBandPseudoColorRenderer(k.dataProvider(), 1, shader) k.setRenderer(renderer) """ Export colored image to file """ export_path = file_in.filePath + ".colored.tif" file_writer = QgsRasterFileWriter(export_path) pipe = QgsRasterPipe() provide = k.dataProvider() # Pipe Setter if not pipe.set(provide.clone()): self.com.error(Bold="PipeProviderError:", String="Cannot set pipe provider", level=1, duration=3) self.com.log( "mainPlug - Color: Pipe provider error on line 473, Continuing...", level=1) self.com.log(str(pipe.renderer()), level=0) pipe.set(renderer.clone()) file_writer.writeRaster(pipe, provide.xSize(), provide.ySize(), provide.extent(), provide.crs()) def run_krig(self): """ Create and run the Krig Window and spoole off the Kriging process for all Layers TODO: Implement a Per layer toggle vs the current only mass layer :return: None """ diag = self.DialogStore[6] from Interpolate import interp diag.show() result = diag.exec_() if result: map_layers = self.iface.mapCanvas().layers() if diag.retProcessallState(): for Index, value in enumerate( map_layers): # type: (int, object) a = interp(iface=self.iface, pointLayer=value) a.run_Output() def run_help(self): """ Display Help Dialog :return: """ self.DialogStore[4].show() def runabout(self): """ Display the About page :return: """ self.DialogStore[2].show()
class FileExport: def __init__(self): """ Export a file as an ASCII tif """ self.com = Communicate() self.filePath = '' self.ExportX = 0 self.ExportY = 0 self.XLLCorner = 0 self.YLLCorner = 0 self.cellSize = 0 self.NoDataValue = -9999 self.DataSet = None def file_output(self, path, x, y, XCorner, YCorner, cellsize, DataSet, NodataValue=-9999): """ Prep the file Output :param path: Path to the Output file :type path: str :param x: Length of the Image :type x: int :param y: Height of the image :type y: int :param XCorner: Where X does it start (From the Bottom left corner) :type XCorner: int :param YCorner: Where does Y Start (From the bottom left corner) :type YCorner: int :param cellsize: What is the resolution of a single cell :type cellsize: int :param DataSet: The final compiled Dataset :type DataSet: list :param NodataValue: Default value if there is no data to fill a box :type NodataValue: int :return: None """ self.filePath = str(path) self.ExportX = x self.ExportY = y self.XLLCorner = XCorner self.YLLCorner = YCorner self.cellSize = cellsize self.NoDataValue = NodataValue self.DataSet = DataSet self.com.log( "FILE OUTPUT PATH SET: {0} | {1} | {2} | {3} | {4} | {5} | {6}". format(self.filePath, self.ExportX, self.ExportY, self.XLLCorner, self.YLLCorner, self.cellSize, self.NoDataValue), 0) def WriteFile(self): """ Write the ASCII TIFF raster file following documentation from http://resources.esri.com/help/9.3/ArcGISengine/java/Gp_ToolRef/Spatial_Analyst_Tools/esri_ascii_raster_format.htm :return: """ OutData = '' for i in self.DataSet: OutData = OutData + str(i) + " " WriteString = "ncols {0}\n" \ "nrows {1}\n" \ "xllcorner {2}\n" \ "yllcorner {3}\n" \ "cellsize {4}\n" \ "nodata_value {5}\n" \ "{6}".format(self.ExportX, self.ExportY, self.XLLCorner, self.YLLCorner, self.cellSize, self.NoDataValue, OutData) if self.filePath != u'': f = open(self.filePath, 'w') f.write(WriteString) self.com.log("File Written", 0) f.close() else: pass
class interp: def __init__(self, pointLayer, iface): """ Setup the Interpolate Function :param pointLayer: The Layer to process :type pointLayer: QgsVectorLayer :param iface: QGIS iface :type iface: iface """ # processing.initialize() self.iface = iface self.com = Communicate(self.iface) self.pLayer = pointLayer self.PredictionLayer = "" self.VarianceLayer = "" def run_Output(self): """ Run the Simplekriging process Fully automated, To change any of the Run Options, Use the params dict If you need help with the algorithm, within the internal Python environment run from processing.core.Processing import processing from processing.tools import * processing.alghelp("saga:simplekriging") # this should display correct usage TODO: Make the output actually go to its own folder (Currently stuck with a escaping problem "\\" ) :return: None """ alg = 'saga:simplekriging' layer = self.pLayer ext = layer.extent() x_min = ext.xMinimum() x_max = ext.xMaximum() y_min = ext.yMinimum() y_max = ext.yMaximum() self.PredictionLayer = os.path.expanduser( "~") + "\\" + self.pLayer.name() self.com.log(String="Path of File" + self.PredictionLayer + "\n", level=0) coords = "%f,%f,%f,%f" % (x_min, x_max, y_min, y_max) params = { "POINTS": self.pLayer, "FIELD": self.pLayer.name(), "TQUALITY": 0, "LOG": False, "BLOCK": False, "DBLOCK": 1, "VAR_MAXDIST": -1, "VAR_NCLASSES": 100, "VAR_NSKIP": 1, "VAR_MODEL": "a+b*x", "OUTPUT_EXTENT": coords, "TARGET_USER_SIZE": 0.000001, "TARGET_USER_FITS": 0, "SEARCH_RANGE": 0, "SEARCH_RADIUS": 1000, "SEARCH_POINTS_ALL": 0, "SEARCH_POINTS_MIN": 4, "SEARCH_POINTS_MAX": 20, "SEARCH_DIRECTION": 0, "PREDICTION": self.PredictionLayer } # params = {"POINTS": iface.activeLayer(), "FIELD": iface.activeLayer().name(), "TQUALITY": 0, "LOG": False, "BLOCK": False, # "DBLOCK": 1, "TARGET_USER_SIZE": 0.000001} processing.runalg(alg, params) self.iface.addRasterLayer(self.PredictionLayer + ".tif", self.pLayer.name() + " Prediction") def get_PredictionLayer(self): """ Return the prediction layer path :return: Path :rtype: str """ return self.PredictionLayer def get_VarianceLayer(self): """ Return the variance layer path (Only works if set internally :return: Path :rtype: str """ return self.VarianceLayer
class IOParse: """ /* Implement CSV Data set functions for Opening reading and passing data internally */ """ def __init__(self, path, iface): """ Take in a file to work on, Initialize and work upon :param path: Path to file :type path: str :param iface: QGIS iface :type iface: iface """ self.iface = iface self.path = path self.com = Communicate(self.iface) try: self.csvFile = open(path, 'rb') except IOError: self.com.error(Bold="IOerror", String="Could not load given File", level=2) except BaseException: self.com.error( Bold="Unknown Error", String="An Unknown Error occured (See log for details", level=2) self.com.log( "IOPARSE Encountered an Unknown error attempting to initialize self.csvFile", level=2) self.Values = 0 self.ValueList = [] self.LayerList = [] def ReadFile(self): """ Read the CSV, Bringing it in to be worked on. Appending to a Value list for later work :return: """ reader = csv.reader(self.csvFile) self.com.log(str(reader), level=0) """ Assume First row is the Values, Each row after that is each data point Using a Key pair store Within a list would look like [{"lat" : value, "Long" : value ... }, {"lat" : Value, "Long" : value ...},...] Current input looks like: ["lat", "long,....], [132, 1322, ...], [...],... """ """ for idx, val in enumerate(reader): for idxi, vali in enumerate(val): if idx == 0: FinalOutput.append(vali) else: FinalOutput[idx-1]""" reader_value = [] for i in reader: reader_value.append(i) self.Values = len(reader_value[0]) - 2 for idx, val in enumerate(reader_value[0]): if idx != 0 and idx != 1 and val != 'ID' or val != 'id' or val != 'Id' or val != 'iD': self.ValueList.append(str(val)) self.add_layer() def add_layer(self): """ Add the Layers to the screen, This function assigns each layer to the screen and creates a Layer List to later match the layer weight TODO: Add in smart deliminator and Decimal assignment :return: None """ file_path = 'file:///%s?crs=%s&delimiter=%s&xField=%s&yField=%s&decimal=%s' % ( self.path, 'EPSG:4326', ',', 'Longitude', 'Latitude', '.') file_input = open(self.path, 'r') comma_separator_pattern = re.compile("\w*(\,)", re.IGNORECASE) decimal = re.compile("\d(\.)", re.IGNORECASE) issue = 0 try: l1 = file_input.readline() l2 = file_input.readline() self.com.log(str(l1), level=0) self.com.log(str(l2), level=0) if comma_separator_pattern.match( l1) == '' or comma_separator_pattern.match(l1) is None: issue = 1 raise IOError if decimal.match(l2) == '' or decimal.match(l2) is None: issue = 2 raise IOError except IOError: # Fail Silently (Due to some current issues where in the Decimal is # not correctly noticed, causing an issue if issue == 1: pass # self.com.error(Bold="DataSampleError:", String="Soil sample data separator is not , (comma)", level=2, # duration=6) elif issue == 2: pass # self.com.error(Bold="DataSampleError:", String="Soil sample Data decimal mark is not . (Period)", # level=2, duration=6) for idx, val in enumerate(self.ValueList): self.LayerList.append( QgsVectorLayer(file_path, val, "delimitedtext")) for i in self.LayerList: QgsMapLayerRegistry.instance().addMapLayer(i) # Get Layers p = QgsMapLayerRegistry.instance().mapLayers() longitude = re.compile("Longitude", re.IGNORECASE) latitude = re.compile("Latitude", re.IGNORECASE) id_pattern = re.compile("ID", re.IGNORECASE) for i in self.LayerList: self.com.log(str(i), level=0) for i in p.keys(): if longitude.match(i) or latitude.match(i) or id_pattern.match(i): QgsMapLayerRegistry.instance().removeMapLayer(i) self.color_layers() def color_layers(self): """ Attempts to assign and color each layer after changing it's renderer to the Categorized Symbol Renderer TODO: Implement a store value to look up default names to get standardized Color Grading, If possible :return: None """ p = QgsMapLayerRegistry.instance().mapLayers() regex = re.compile("\n?(\D*)\d*\n?") for key, val in p.iteritems(): try: catagories = [] a = regex.match(key) fcn = QgsVectorGradientColorRampV2() # renderer.setWeightExpression(a.group(1)) # fcn.setColor1(QColor(255, 255, 255, 0)) # fcn.setColor2(QColor(random.randint(0, 100), random.randint( # 50, 255), random.randint(50, 255), 255)) fcn.setColor1(QColor(255, 0, 0, 255)) fcn.setColor2(QColor(0, 255, 0, 255)) # self.com.log(str(fcn.stops()), level=0) fcn.setStops([QgsGradientStop(0.5, QColor(255, 207, 74, 255))]) # renderer.setColorRamp(fcn) # renderer.setRenderQuality(1) # Max out the quality # for feature in val.getFeature(): # print feature.attribute(a.group(1)) fni = val.fieldNameIndex(a.group(1)) # This function is accomplishing the Classify Function, due to # the lack of API implementation sortedlist = [] for unique in val.dataProvider().uniqueValues(fni): sortedlist.append(unique) sortedlist.sort() for i in sortedlist: symbol = QgsSymbolV2.defaultSymbol(val.geometryType()) category = QgsRendererCategoryV2(i, symbol, str(i)) catagories.append(category) renderer = QgsCategorizedSymbolRendererV2( a.group(1), catagories) self.com.log(str(renderer.categories()), level=0) renderer.updateColorRamp(fcn) # renderer.updateCategoryValue(a.group(1)) val.setRendererV2(renderer) except AttributeError: # This will allow the Color step to continue if it hits an # Object it can't use (Raster layer) continue
class IOParse: """ /* Implement CSV Data set functions for Opening reading and passing data internally */ """ def __init__(self, path, iface): self.iface = iface self.path = path self.com = Communicate(self.iface) try: self.csvFile = open(path, 'rb') except IOError: self.com.error( Bold="IOerror", String="Could not load given File", level=2) except: self.com.error( Bold="Unknown Error", String="An Unknown Error occured (See log for details", level=2) self.com.log( "IOPARSE Encountered an Unknown error attempting to initialize self.csvFile", level=2) self.Values = 0 self.ValueList = [] self.LayerList = [] def ReadFile(self): """ Read the CSV, Bringing it in to be worked on. Appending to a Value list for later work :return: """ reader = csv.reader(self.csvFile) self.com.log(str(reader), level=0) """ Assume First row is the Values, Each row after that is each data point Using a Key pair store Within a list would look like [{"lat" : value, "Long" : value ... }, {"lat" : Value, "Long" : value ...},...] Current input looks like: ["lat", "long,....], [132, 1322, ...], [...],... """ """ for idx, val in enumerate(reader): for idxi, vali in enumerate(val): if idx == 0: FinalOutput.append(vali) else: FinalOutput[idx-1]""" reader_value = [] for i in reader: reader_value.append(i) self.Values = len(reader_value[0]) - 2 for idx, val in enumerate(reader_value[0]): if idx != 0 and idx != 1 and val != 'ID' or val != 'id' or val != 'Id' or val != 'iD': self.ValueList.append(str(val)) self.add_layer() def add_layer(self): """ Add the Layers to the screen, This function assigns each layer to the screen and creates a Layer List to later match the layer weight :return: None """ # TODO: Add in smart deliminator and Decimal assignment, NOTE regex # might not work due to this being a bit more complex file_path = 'file:///%s?crs=%s&delimiter=%s&xField=%s&yField=%s&decimal=%s' % (self.path, 'EPSG:4326', ',', 'Longitude', 'Latitude', '.') file_input = open(self.path, 'r') comma_separator_pattern = re.compile("\w*(\,)", re.IGNORECASE) decimal = re.compile("\d(\.)", re.IGNORECASE) issue = 0 try: l1 = file_input.readline() l2 = file_input.readline() self.com.log(str(l1), level=0) self.com.log(str(l2), level=0) if comma_separator_pattern.match( l1) == '' or comma_separator_pattern.match(l1) is None: issue = 1 raise IOError if decimal.match(l2) == '' or decimal.match(l2) is None: issue = 2 raise IOError except IOError: # Fail Silently (Due to some current issues where in the Decimal is # not correctly noticed, causing an issue if issue == 1: pass # self.com.error(Bold="DataSampleError:", String="Soil sample data separator is not , (comma)", level=2, # duration=6) elif issue == 2: pass # self.com.error(Bold="DataSampleError:", String="Soil sample Data decimal mark is not . (Period)", # level=2, duration=6) for idx, val in enumerate(self.ValueList): self.LayerList.append(QgsVectorLayer( file_path, val, "delimitedtext")) for i in self.LayerList: QgsMapLayerRegistry.instance().addMapLayer(i) # Get Layers p = QgsMapLayerRegistry.instance().mapLayers() longitude = re.compile("Longitude", re.IGNORECASE) latitude = re.compile("Latitude", re.IGNORECASE) id_pattern = re.compile("ID", re.IGNORECASE) for i in self.LayerList: self.com.log(str(i), level=0) for i in p.keys(): if longitude.match(i) or latitude.match(i) or id_pattern.match(i): QgsMapLayerRegistry.instance().removeMapLayer(i) self.color_layers() def color_layers(self): """ Attempts to assign and color each layer after changing it's renderer to a heatmap renderer NOTE: This uses a Random sequence for color grading TODO: Update color grading to generally output more readable colors Possibly make higher values have more radius? :return: None """ p = QgsMapLayerRegistry.instance().mapLayers() regex = re.compile("\n?(\D*)\d*\n?") for key, val in p.iteritems(): try: renderer = QgsHeatmapRenderer() a = regex.match(key) fcn = QgsVectorGradientColorRampV2() renderer.setWeightExpression(a.group(1)) fcn.setColor1(QColor(255, 255, 255, 0)) fcn.setColor2(QColor(random.randint(0, 100), random.randint( 50, 255), random.randint(50, 255), 255)) renderer.setColorRamp(fcn) renderer.setRenderQuality(1) # Max out the quality val.setRendererV2(renderer) except AttributeError: continue
class RasterManip: def __init__(self, iface): # type: (object) -> object """ The work horse of the NDVI calculations, named rasterManip due to it's older functions :param iface: The iface passed in from mainPlug """ self.iface = iface self.com = Communicate(self.iface) @staticmethod def return_dataset(X, Y, rLayer): """ Return back the Results of a XY Cordnate pair :param X: X Co-ordnate :param Y: Y Co-Ordnate :return: The Tuple containing the values from the raster """ ident = rLayer.dataProvider().identify(QgsPoint(X, Y), QgsRaster.IdentifyFormatValue) if ident.isValid(): return ident.results() return ident.results() @staticmethod def do_ndvi_calc(DataSet, DataSet2=None): """ To per pixel Calculations to measure NDVI of 1 multiband image or two Single-band-grey images DEPRECATED :param DataSet: Mandatory, Single or multiband image :param DataSet2: Optional, Singleband Image :return: Resulting Calculated NDVI normalized dataset """ resul = [] # Single raster if DataSet2 is None: for i in DataSet: if i is not None: a = (i.get(3) - i.get(1)) / (i.get(3) + i.get(1)) resul.append(a) else: resul.append(-9999) return resul # Multi raster else: for idx, val in enumerate(DataSet): # if val is not None: a = (val.get(1) - DataSet2[idx].get(1)) / \ (val.get(1) + DataSet2[idx].get(1)) resul.append(a) # else: gc.collect() return resul @staticmethod def processing_ndvi_calc(rLayer1, rLayer2, path): """ Older deprecated NDVI handler, This is simply the template for the monstrosity that the current one has become :param rLayer1: rLayer 1 Object :param rLayer2: rLayer 2 Object :param path: Path to Output too :return: None """ path = path r1 = QgsRasterCalculatorEntry() r2 = QgsRasterCalculatorEntry() r1.ref = "rLayer@1" r2.ref = "rLayer@2" r1.raster = rLayer1 r2.raster = rLayer2 r1.bandNumber = 1 r2.bandNumber = 1 entries = [r1, r2] expression = "(\"{0}\"-\"{1}\")/(\"{2}\"+\"{3}\")".format( r1.ref, r2.ref, r1.ref, r2.ref) a = QgsRasterCalculator(expression, path, 'GTiff', rLayer1.extent(), rLayer1.width(), rLayer1.height(), entries) a.processCalculation() def rastercalcmulti_ndvi(self, rLayer1, path, calctype, rLayer2=None, r1Band=1, r2Band=1, rLayer3=None, r3Band=1): """ Calculate any type of NDVI like Calculation from various types of Cameras be they: Multi output, NGB, RGB, NR :param r1Band: first Raster Layer Band number :param rLayer3: third rLayer object :param r3Band: third Raster band :param rLayer1: first rLayer object :param path: path to Output :param calctype: Calculation to perform :param rLayer2: second rLayer object :param r2Band: band Number :return: None """ """ TODO: Add support for Multiple different Raster types, be they Single Raster (Of NGB, RGB or otherwise) or Multiraster https://maxmax.com/ndv_historyi.htm Implement NDVI Red NDVI blue and ENDVI (Enhanced NDVI) """ if path == '' or path is None: self.com.log( "No Path on NDVI calc function, This will likely cause an error", level=2) path = path r1 = QgsRasterCalculatorEntry() r2 = QgsRasterCalculatorEntry() r3 = QgsRasterCalculatorEntry() exporttype = "GTiff" # Do variable creation r1.raster = rLayer1 r1.bandNumber = r1Band r2.bandNumber = r2Band r3.bandNumber = r3Band r1.ref = 'Input1@1' r2.ref = 'Input2@1' r3.ref = 'Input3@1' if r1Band is None: r1.bandNumber = 1 if rLayer2 is not None: r2.raster = rLayer2 if rLayer3 is not None: r3.raster = rLayer3 entries = [] if calctype is None: self.com.error(String="Calctype None", level=2) elif calctype == "NDVI": # This assumes that that rLayer1 is N and rLayer2 is R entries.append(r1) entries.append(r2) expression = "(\"{0}\"-\"{1}\")/(\"{2}\"+\"{3}\")".format( r1.ref, r2.ref, r1.ref, r2.ref) a = QgsRasterCalculator(expression, path, exporttype, rLayer1.extent(), rLayer1.width(), rLayer1.height(), entries) a.processCalculation() elif calctype == "bNDVI": # This assumes that rLayer1 in N and rLayer2 is B entries.append(r1) entries.append(r2) expression = "(\"{0}\"-\"{1}\")/(\"{2}\"+\"{3}\")".format( r1.ref, r2.ref, r1.ref, r2.ref) a = QgsRasterCalculator(expression, path, exporttype, rLayer1.extent(), rLayer1.width(), rLayer1.height(), entries) a.processCalculation() elif calctype == "ENDVI": # This assumes that rLayer1 is N, rLayer2 is Green and rLayer3 is # Blue entries.append(r1) entries.append(r2) entries.append(r3) expression = "((\"{0}\"+\"{1}\")-(2*\"{2}\"))/((\"{0}\"+\"{1}\")+(2*\"{2}\"))".format( r1.ref, r2.ref, r3.ref) a = QgsRasterCalculator(expression, path, exporttype, rLayer1.extent(), rLayer1.width(), rLayer1.height(), entries) a.processCalculation() elif calctype == "EVI": entries.append(r1) entries.append(r2) entries.append(r3) expression = "2.5*(\"{0}\"-\"{1}\")/(\"{0}\"+6*\"{1}\"-7.5*\"{2}\"+1)".format( r1.ref, r2.ref, r3.ref) a = QgsRasterCalculator(expression, path, exporttype, rLayer1.extent(), rLayer1.width(), rLayer1.height(), entries) a.processCalculation() else: self.com.error(Bold="CalcType Error", String="Unrecognized calctype", level=2)