""" This is a log with graphic assays along log or drill extension. It gives user a means to visualize data and to compare them. Data must be numeric (float) like mining grade or other physic parameters..... Labriki M. June. 2021 """ from qgis.core import * from PyQt5.QtGui import * from PyQt5.QtCore import * from qgis.PyQt.QtCore import QVariant from qgis.utils import * from qgis.gui import * from os import path from pathlib import Path import processing from random import randrange import time # qid = QInputDialog() canvas = iface.mapCanvas() # input, Filepathin = QInputDialog.getText(qid, "Filepath 'input' for csv:", "Filepath 'input' like this:\n/Users/HP/Documents/loglitho.csv\n" + " - The file to load must be a csv format", QLineEdit.Normal, "/Users/HP/Documents/AssaysLog.csv") if Filepathin: filepathin = str(input.split()[0]) way = "'" + filepathin + "'" print(way) #is file exist? if os.path.isfile(filepathin): print("Fichier trouvé") else: print("Fichier non trouvé") iface.messageBar().pushMessage("Error","File "+ way + " not found, verifiy your path", level=1,duration=10) self.iface.actionExit().trigger() inputlayer = filepathin #look for fields from and to and hardness input, NameFields = QInputDialog.getText(qid, "Title of fiels from - to and Hardness", "Fields title corresponding to:\n- from_m\n- to_m\n- relative hardness of the rocks to have erosion component in log in decimal number >=1\n"+ "- code of your lithological discription", QLineEdit.Normal, "from_m,to_m,hardness,code") if NameFields: from_m = str(input.split(",")[0]) to_m = str(input.split(",")[1]) hard = str(input.split(",")[2]) code = str(input.split(",")[3]) if not NameFields: iface.messageBar().pushMessage("Error","Program aborted", level=2,duration=5) self.iface.actionExit().trigger() #select a non earth epsg or equivalent like 3006 input, Non_Earth = QInputDialog.getText(qid, "Non-Earth projection", "It's important to have a non-earth projection or equivalent like:\n" + "scr : SWEREF99TM\n" + "EPSG: 3006\n" + " - Give your equivalent non-earth projection. Let this USER:\n3006", QLineEdit.Normal, "3006") if Non_Earth: proj = str(input.split(",")[0]) xp_epsg='Polygon?crs=epsg:' + proj #output file input, Filepathout = QInputDialog.getText(qid, "Folder path 'ouput':", "Output folder path, like this:\n/Users/HP/Documents/", QLineEdit.Normal, "/Users/HP/Documents/") if Filepathout: FilePathout = str(input.split()[0]) #File gpkg input, FileName = QInputDialog.getText(qid, "Name file for your 'output':", "Output file name like:\nFieldLog.gpkg", QLineEdit.Normal, "FieldLog.gpkg") if FileName: FileName = str(input.split()[0]) crs = int(proj) # set the crs as needed #-------------------- #outputlayer = filepathout # set the filepath for the output shapefile outputlayer = FilePathout + FileName print(outputlayer) #-------------------- spatRef = QgsCoordinateReferenceSystem(crs, QgsCoordinateReferenceSystem.EpsgCrsId) #--------------------- inp_tab = QgsVectorLayer(inputlayer, 'Input_Table', 'ogr') pr_ = inp_tab.dataProvider() inp_tab.updateFields() fields = inp_tab.fields() field_names = [field.name() for field in pr_.fields()] outLayer = QgsVectorFileWriter(outputlayer, None, fields, QgsWkbTypes.Polygon, spatRef, "gpkg") #--------------------- pt = QgsPointXY() outFeature = QgsFeature() scale = 0. scale_0 = 0. points=[] scale_list = [] list_ten = [] list_ten = [] max_list = 0. min_list = 0. #from_list = [] to_list = [] n = 0 count = 0 #--- for feat in inp_tab.getFeatures(): #--------------------- n = n + 1 # l = l + 1 count = count + 1 attrs = feat.attributes() from_m = -1*float(attrs[1]) to_m = -1*float(attrs[2]) scale = float(attrs[3]) # from_list.append(from_m) # print(from_m) # scale_list.append(scale) if from_m == 0 and n != 1: max_list = max_list + max(scale_list)+20 #initialize scale_list n = 0 scale_list[:] = [] #Create polygons from each pass points.append(QgsPointXY(scale_0 + max_list,from_m)) # a2 = (scale, from_m) 2 points.append(QgsPointXY(scale + max_list,from_m)) # a3 = (scale, to_m) 3 points.append(QgsPointXY(scale + max_list,to_m)) # a4 = (scale, to_m) 4 points.append(QgsPointXY(scale_0 + max_list,to_m)) #finalize realizations outFeature.setGeometry(QgsGeometry.fromPolygonXY([points])) outFeature.setAttributes(attrs) outLayer.addFeature(outFeature) scale_list.append(scale) #initialize parameters and list scale = 0. points[:] = [] #terminate loop del outLayer #call layer to canvas layer = QgsVectorLayer(outputlayer,FileName,'ogr') QgsProject.instance().addMapLayer(layer) features = layer.getFeatures() #position in list of code_lithology list = layer.fields().names() code = list[5] #--------------------------------------------- #symbology: create a random symbology in the logs #using code field #Create symbology for all categorized entities fni = layer.fields().indexFromName(code) unique_values = layer.uniqueValues(fni) # fill categories categories = [] for unique_value in unique_values: # initialize the default symbol for this geometry type symbol = QgsSymbol.defaultSymbol(layer.geometryType()) # configure a symbol layer layer_style = {} layer_style['color'] = '%d, %d, %d' % (randrange(0, 256), randrange(0, 256), randrange(0, 256)) layer_style['outline'] = '#000000' symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style) # replace default symbol layer with the configured one if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) # create renderer object category = QgsRendererCategory(unique_value, symbol, str(unique_value)) # entry for the list of category items categories.append(category) # create renderer object renderer = QgsCategorizedSymbolRenderer(code, categories) # assign the created renderer to the layer if renderer is not None: layer.setRenderer(renderer) layer.triggerRepaint() #add a provisoir field for this layer #use it to have abscisss of many logs to cretae scales prov = layer.dataProvider() field_names = [field.name() for field in prov.fields()] #print(field_names) for count, f in enumerate(field_names): print("{}:{}".format(count, f)) #add x_log as double features = layer.getFeatures() prov.addAttributes([QgsField("x_log", QVariant.Double)]) #layer.startEditing() for f in features: id=f.id() attrs = f.attributes() dur = float(attrs[4]) valeur= dur val = valeur + 20 attr_value={count+1:val} prov.changeAttributeValues({id:attr_value}) layer.updateFields() layer.commitChanges() #========= #memory layer with non-earth projection scale = QgsVectorLayer("LineString?crs=EPSG:3006","Scale","memory") pr = scale.dataProvider() pr.addAttributes([QgsField("niveau", QVariant.Int)]) scale.updateFields() line = QgsFeature() field_mem = [field.name() for field in pr.fields()] #activate layer (log layers FieldLog.gpkg) layer = qgis.utils.iface.activeLayer() # get active layer if not already set prov = layer.dataProvider() #field_names = [field.name() for field in prov.fields()] #print(field_names) features = layer.getFeatures() list_from = [] list_to = [] list_xlog = [] list_x = [] list_len = [] list_rap = [] abcisse = [0] # list_ten = [] list_ten_to = [] l = 0 max_xlog = 0. max_to = 0. n = 0 x = 0. x0 = 0. for f in features: n = n + 1 attrs = f.attributes() from_m = float(attrs[2]) to_m = float(attrs[3]) # if n > 4: # ten = float(attrs[n]) xlog = float(attrs[-1]) list_xlog.append(xlog) list_to.append(to_m) list_from.append(from_m) if from_m == min(list_from) and n > 1: # list_x.append(max(list_xlog)) list_len.append(max(list_to)) x = x + max(list_xlog) abcisse.append(x) #......... #......... list_xlog[:] = [] # list_to[:] = [] #print("liste_len:", list_len) #create parameters (list, and variables) rapport = [] list_len.append(to_m) s = sum(list_len) if s <= 100: rapport = 1 else: rapport = s/100 #initialize variables i = 0 j = 0 val1 = 0. # nto = int((max(list_to) - min(list_from))) #list_from_scale = [] #list_from_scale = [int(x + nto) for x in (list_from)] # # while j <= nto: point1 = QgsPoint(0,-min(list_from) - j) if j % 10 == 0: point2 = QgsPoint((-(1*rapport)),-min(list_from) - j) else: point2 = QgsPoint((-(0.5*rapport)),-min(list_from) - j) line.setGeometry(QgsGeometry.fromPolyline([point1,point2])) line.setAttributes([min(list_from) + j]) pr.addFeature(line) scale.updateExtents() j += 1 QgsProject.instance().addMapLayer(scale) #======== layer = iface.activeLayer() # create a new symbol fro layer 'Scale' symbol = QgsLineSymbol.createSimple({'line_style': 'continue', 'color': 'black'}) symbol.setWidth(0.25) # apply symbol to layer renderer layer.renderer().setSymbol(symbol) # repaint the layer layer.triggerRepaint() #======== # layers= QgsProject.instance().mapLayersByName(FileName)[0] # I select the layer object iface.setActiveLayer(layers) prov = layers.dataProvider() field_names = [field.name() for field in prov.fields()] #delete th provisoir layer x_log list_layer = [] #last = [] for f in field_names: list_layer.append(f) #list_layer.reverse() n_xlog = len(list_layer)-1 prov.deleteAttributes([n_xlog]) #to prepar linegraphe of elements features = layers.getFeatures() a = 0 b = 0 c = 0 list_from = [] list_to = [] list_dur = [] list_6 = [] list_7= [] list_8= [] list_9= [] list_10= [] for count, f in enumerate(field_names): print("{}:{}".format(count, f)) #List of grade of present elements #print("count: ",count) #----- for f in features: id=f.id() attrs = f.attributes() # list_from.append(float(attrs[2])) list_to.append(float(attrs[3])) list_dur.append(float(attrs[4])) # # 1st analys list_6.append(float(attrs[6])) # 2nd analys try: list_7.append(float(attrs[7])) except IndexError: pass # continue # 3rd analys try: list_8.append(float(attrs[8])) except IndexError: pass # continue # 4th analys try: list_9.append(float(attrs[9])) except IndexError: pass # continue # 5th analys try: list_10.append(float(attrs[10])) except IndexError: pass continue # # list_val = [list_6]+[list_7]+[list_8]+[list_9]+[list_10] #print("list_val: ", list_val) #middle of pass mid = [] mid = [-1*(fromm+tom)/2 for fromm, tom in zip(list_from, list_to)] #print(mid) #exaggeration of grade scale input, exag = QInputDialog.getText(qid, "Data exaggeration value", "Integer exaggeration of grade to have details in linegraph: n >= 1.\n" + "It's important to signal exageration for each data in your list.\n" + "Ex: if you have just 3 data then give just 3;\notherwise the script will aborted.\n" + "List of your data:\n" + str(field_names[6:-1]) + "\nExaggeration, for 5 elements for example, must been like this:", QLineEdit.Normal, "1,5,1,3,1") if exag: exag = input.split() #print("ex: ", exag) #inreval to add at grade #list 6 x = 0 exag6 = int(input.split(",")[0]) maxdur = max(list_dur) list_6[:] = [(x * exag6) + maxdur + 10 for x in list_6] max6 = max(list_6) try: x = 0 exag7 = int(input.split(",")[1]) list_7[:] = [(x * exag7) + max6 + 10 for x in list_7] max7 = max(list_7) except IndexError: pass #list 8 try: x = 0 exag8 = int(input.split(",")[2]) list_8[:] = [(x * exag8) + max7 + 10 for x in list_8] max8 = max(list_8) except IndexError: pass #list_9 try: x = 0 exag9 = int(input.split(",")[3]) list_9[:] = [(x * exag9) + max8 + 10 for x in list_9] max9 = max(list_9) except IndexError: pass #list 10 try: x = 0 exag10 = int(input.split(",")[4]) list_10[:] = [(x * exag10) + max9 + 10 for x in list_10] max10 = max(list_10) except IndexError: pass #------ grade = QgsVectorLayer("LineString?crs=EPSG:3006","Grade","memory") pr = grade.dataProvider() pr.addAttributes([QgsField("grade", QVariant.String, "texte",20)]) pr.addAttributes([QgsField("element", QVariant.String, "texte",20)]) grade.updateFields() line = QgsFeature() prov = layer.dataProvider() field_grade = [field.name() for field in pr.fields()] #### for i in range(len(list_val)): # print("list: ", i, list_val[i]) if list_val[i] != []: coords = [QgsPoint(ten, pas) for ten, pas in zip(list_val[i], mid)] grade.updateExtents() layer.startEditing() line.setGeometry(QgsGeometry.fromPolyline(coords)) line.setAttributes([i+6,field_names[i+6]]) pr.addFeature(line) grade.updateExtents() layer.commitChanges() QgsProject.instance().addMapLayer(grade) #Random style of linegraphe layer = iface.activeLayer() features = layer.getFeatures() #position in list of code_lithology list = layer.fields().names() code_element = list[1] fni = layer.fields().indexFromName(code_element) unique_values = layer.uniqueValues(fni) # fill categories categories = [] for unique_value in unique_values: # initialize the default symbol for this geometry type symbol = QgsSymbol.defaultSymbol(layer.geometryType()) # configure a symbol layer # initialize the default symbol for this geometry type symbol = QgsSymbol.defaultSymbol(layer.geometryType()) # configure a symbol layer layer_style = {} layer_style['color'] = '%d, %d, %d' % (randrange(0, 256), randrange(0, 256), randrange(0, 256)) layer_style['outline'] = '#000000' symbol.setWidth(0.40) symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style) # replace default symbol layer with the configured one if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) # create renderer object category = QgsRendererCategory(unique_value, symbol, str(unique_value)) # entry for the list of category items categories.append(category) # create renderer object renderer = QgsCategorizedSymbolRenderer(code_element, categories) # assign the created renderer to the layer if renderer is not None: layer.setRenderer(renderer) layer.triggerRepaint() #Labelling the grades #from csv where is an indicate of units (like Pb_%, or Co_ppm) #Axes for grades gradeaxes = QgsVectorLayer("LineString?crs=EPSG:3006","GradeAxes","memory") pr = gradeaxes.dataProvider() pr.addAttributes([QgsField("val", QVariant.Double)]) # gradeaxes.updateFields() line = QgsFeature() prov = layer.dataProvider() field_gradeaxes = [field.name() for field in pr.fields()] #axes_x and axes_y i = 0 minax = 0. maxax = 0. maxy = -1 * max(list_to) for i in range(len(list_val)): if list_val[i] != []: minax = min(list_val[i]) maxax = max(list_val[i]) # print(minax, maxax) point1 = QgsPoint(minax, - 1 * min(list_from)) point2 = QgsPoint(maxax, - 1 * min(list_from)) layer.startEditing() line.setGeometry(QgsGeometry.fromPolyline([point1, point2])) # line.setGeometry(QgsGeometry.fromPolyline([point1, point3])) pr.addFeature(line) gradeaxes.updateExtents() layer.commitChanges() QgsProject.instance().addMapLayer(gradeaxes) #Horizontal Scale #interval = 0 k = 0 x = 0 ten = 0. for i in range(len(field_names[6:-1])): diff = int((max(list_val[i])-(min(list_val[i])))/4) # print("dif: ", diff) listaxe = [] listaxetotal = [] for j in range(5): # print("list: ", j,"-", min(list_val[i]) + (j * diff)) p = min(list_val[i]) + (j * diff) # print("p: ", p) point1 = QgsPoint(p, -1 * min(list_from)) point2 = QgsPoint(p, -1 - min(list_from)) if i == 0: ten = round(((p - maxdur - 10)/exag6),2) if i == 1: ten = round(((p - max6 - 10)/exag7),2) if i == 2: ten = round(((p - max7 - 10)/exag8),2) if i == 3: ten = round((p - max8 - 10)/exag9,2) if i == 4: ten = round((p - max9 - 10)/exag10,2) # print("ten: ", i,"-", ten) layer.startEditing() line.setGeometry(QgsGeometry.fromPolyline([point1, point2])) line.setAttributes([ten]) pr.addFeature(line) grade.updateExtents() layer.commitChanges() QgsProject.instance().addMapLayer(gradeaxes) # layer = iface.activeLayer() #features = layer.getFeatures() # create a new symbol symbol = QgsLineSymbol.createSimple({'line_style': 'continue', 'color': 'black'}) symbol.setWidth(0.25) # apply symbol to layer renderer layer.renderer().setSymbol(symbol) # repaint the layer layer.triggerRepaint() #labels for layers #Grade labels layer_1 = QgsProject().instance().mapLayersByName('Grade')[0] for layer in QgsProject.instance().mapLayers().values(): layer_settings = QgsPalLayerSettings() text_format = QgsTextFormat() text_format.setFont(QFont("Arial", 6)) text_format.setSize(6) layer_settings.setFormat(text_format) layer_settings.fieldName = "element" layer_settings.placement = 2 layer_settings.enabled = True layer_settings = QgsVectorLayerSimpleLabeling(layer_settings) layer_1.setLabelsEnabled(True) layer_1.setLabeling(layer_settings) layer_1.triggerRepaint() #Scale labels with expression layer_2 = QgsProject().instance().mapLayersByName('Scale')[0] for layer in QgsProject.instance().mapLayers().values(): settings = QgsPalLayerSettings() format = QgsTextFormat() format.setFont(QFont('Arial', 6)) format.setColor(QColor('Black')) settings.setFormat(format) settings.fieldName = "if(niveau%10=0,concat(niveau,'m'),'')" settings.isExpression = True labels = QgsVectorLayerSimpleLabeling(settings) layer_2.setLabelsEnabled(True) layer_2.setLabeling(labels) layer_2.triggerRepaint() #Labels for GradeAxes layer_3 = QgsProject().instance().mapLayersByName('GradeAxes')[0] for layer in QgsProject.instance().mapLayers().values(): settings = QgsPalLayerSettings() format = QgsTextFormat() format.setFont(QFont('Arial', 5)) format.setColor(QColor('Black')) settings.setFormat(format) settings.fieldName = "val" settings.isExpression = True labels = QgsVectorLayerSimpleLabeling(settings) layer_3.setLabelsEnabled(True) layer_3.setLabeling(labels) layer_3.triggerRepaint() #axe_lenght lengthaxes = QgsVectorLayer("LineString?crs=EPSG:3006","LengthAxes","memory") pr = lengthaxes.dataProvider() pr.addAttributes([QgsField("Axes", QVariant.Double)]) lengthaxes.updateFields() line = QgsFeature() prov = layer.dataProvider() field_lengthaxes = [field.name() for field in pr.fields()] i = 0 minax = 0. maxax = 0. maxy = -1 * max(list_to) for i in range(len(list_val)): if list_val[i] != []: minax = min(list_val[i]) point1 = QgsPoint(minax, -1 * min(list_to)) point3 = QgsPoint(minax, maxy) lengthaxes.updateExtents() layer.startEditing() line.setGeometry(QgsGeometry.fromPolyline([point1, point3])) line.setAttributes([i]) pr.addFeature(line) # grade.updateExtents() layer.commitChanges() QgsProject.instance().addMapLayer(lengthaxes) #style of LengthAxes (white color to hide zero rade value) layer = iface.activeLayer() # create a new symbol symbol = QgsLineSymbol.createSimple({'line_style': 'continue', 'color': 'white'}) symbol.setWidth(1) layer.renderer().setSymbol(symbol)