Source code for gwa.code.extract

#!/usr/bin/python
# -*- coding: utf-8 -*-

from xml.etree.cElementTree import Element, ElementTree, SubElement
import DBA
import cairo
import time
import re
from transformation import *

[docs]class Extract: """ Purpose to extract campaign data measure in XML or PNG file. :arguments: - id_campaign (type integer) Represents the numbre of campaign which we want extract data. - fichier (type string) Chose the name of extraction **exemple** >>> id_campaign = 2 >>> fichier = 'essai_extract' ex = Extract(id_campaign,fichier) ex.toXML() ex.toPNG() """ def __init__(self,id_area_arg,id_place_arg,id_ap_arg,id_campaign_arg,fichier_arg,main=None): """ Recovery of generic parameters such as: * the area number * the number or numbers of the square * the number or numbers of ap * the number or numbers of the campaign * name of the extract file """ self.main_app=main self.id_area = id_area_arg self.id_place = id_place_arg self.id_ap = id_ap_arg self.id_campaign = id_campaign_arg self.fichier = fichier_arg self.db = DBA.DBConnect(main=self.main_app)
[docs] def toXML(self): """ The function 'toXML' permit to extract information from an XML file in BDD The XML file follows the new version of the database :return: file .xml created on the current directory """ #Date recovery date = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime()) #Tag GWA gwa = Element("gwa", {'date':date, 'xmlns:xsi':"http://www.w3.org/2001/XMLSchema-instance", 'xsi:schemaLocation':"http://gwa.sourceforge.net/extract/gwaExtract.xsd"}) #Queries SQL area area_list = self.db.select('area',\ ['id_area','name','width','length', 'height', 'x_coordinate_area', 'y_coordinate_area', 'z_coordinate_area', 'description', 'origin_info'],\ {'id_area':self.id_area}) #loop on the area for id_area_sql, name_area_sql, width_area_sql, length_area_sql, height_area_sql, x_coordinate_area_sql, y_coordinate_area_sql, z_coordinate_area_sql, description_area_sql, origin_info_area_sql in area_list: #Balise AREA area = Element("area") #AREA arguments nameArea = Element("nameArea") nameArea.text = name_area_sql.decode("utf-8") area.append(nameArea) widthArea = Element("widthArea") widthArea.text = str(width_area_sql).decode("utf-8") area.append(widthArea) lengthArea = Element("lengthArea") lengthArea.text = str(length_area_sql).decode("utf-8") area.append(lengthArea) heightArea = Element("heightArea") heightArea.text = str(height_area_sql).decode("utf-8") area.append(heightArea) x_coordinate_area_origin = Element("x_coordinate_area_origin") x_coordinate_area_origin.text = str(x_coordinate_area_sql).decode("utf-8") area.append(x_coordinate_area_origin) y_coordinate_area_origin = Element("y_coordinate_area_origin") y_coordinate_area_origin.text = str(y_coordinate_area_sql).decode("utf-8") area.append(y_coordinate_area_origin) z_coordinate_area_origin = Element("z_coordinate_area_origin") z_coordinate_area_origin.text = str(z_coordinate_area_sql).decode("utf-8") area.append(z_coordinate_area_origin) descriptionArea = Element("descriptionArea") descriptionArea.text = u""+description_area_sql.decode("utf-8") area.append(descriptionArea) origin_infoArea = Element("origin_infoArea") origin_infoArea.text = origin_info_area_sql.decode("utf-8") area.append(origin_infoArea) #loop on the places self.__place(area, id_area_sql) gwa.append(area) #Call the function prettyprint self.__prettyprint(gwa) #Creation of the tree xmltree = ElementTree(gwa) #Write file xmltree.write(self.fichier, encoding="utf-8")
def __place(self, area, id_area): """ The function '__place()' permit writting XML file for the part of place :argument: area (type Element) Top tag id_area (type Int) area number """ #Loop on the places selected by the user for id_place_user in self.id_place: #Queries SQL place place_list = self.db.select('place',\ ['id_place', 'name', 'width', 'length', 'height', 'x_coordinate_area', 'y_coordinate_area', 'z_coordinate_area', 'angle', 'description', 'origin_info'],\ {'id_area':id_area, 'id_place':id_place_user}) #Loop on the places for id_place_ap, name_place_ap, width_place_ap, length_place_ap, height_place_ap, x_coordinate_area_place_ap, y_coordinate_area_place_ap,\ z_coordinate_area_place_ap, angle_place_ap, description_place_ap, origin_info_place_ap in place_list: #Tag PLACE place = Element("place") id_place = id_place_ap #PLACE arguments namePlace = Element("namePlace") namePlace.text = name_place_ap.decode("utf-8") place.append(namePlace) widthPlace = Element("widthPlace") widthPlace.text = str(width_place_ap).decode("utf-8") place.append(widthPlace) lengthPlace = Element("lengthPlace") lengthPlace.text = str(length_place_ap).decode("utf-8") place.append(lengthPlace) heightPlace = Element("heightPlace") heightPlace.text = str(height_place_ap).decode("utf-8") place.append(heightPlace) x_coordinate_area = Element("x_coordinate_area") x_coordinate_area.text = str(x_coordinate_area_place_ap).decode("utf-8") place.append(x_coordinate_area) y_coordinate_area = Element("y_coordinate_area") y_coordinate_area.text = str(y_coordinate_area_place_ap).decode("utf-8") place.append(y_coordinate_area) z_coordinate_area = Element("z_coordinate_area") z_coordinate_area.text = str(z_coordinate_area_place_ap).decode("utf-8") place.append(z_coordinate_area) angle = Element("angle") angle.text = str(angle_place_ap).decode("utf-8") place.append(angle) #Creation of the matrix transformation self.trans_g = Transformation(x_coordinate_area_place_ap, y_coordinate_area_place_ap, z_coordinate_area_place_ap, angle_place_ap) descriptionPlace = Element("descriptionPlace") descriptionPlace.text = description_place_ap.decode("utf-8") place.append(descriptionPlace) origin_infoPlace = Element("origin_infoPlace") origin_infoPlace.text = origin_info_place_ap.decode("utf-8") place.append(origin_infoPlace) #Loop on the campaign self.__campaign(place, id_place) area.append(place) def __campaign(self, place, id_place): """ The function '__campaign()' permit writting XML file for the part of campaign :argument: place (type Element) Top tag id_place (type Int) Place number """ #Loop on campaigns selected by the user for id_campaign_user in self.id_campaign: #Queries SQL campaign campaign_list = self.db.select('campaign',\ ['id_campaign','name','x_step','y_step','z_step','date','eperf_parameters','rts_cts','fragment','tx_power'],\ {'id_place':id_place,'id_campaign':id_campaign_user}) #Loop on the campaign for id_campaign_sql, name_campaign_sql, x_step_campaign_sql, y_step_campaign_sql, z_step_campaign_sql, date_campaign_sql,\ eperf_parameters_campaign_sql, rts_cts_campaign_sql, fragment_campaign_sql, tx_power_campaign_sql in campaign_list: #Tag CAMPAIGN campaign = Element("campaign") id_campaign = id_campaign_sql #CAMPAIGN Arguments nameCampaign = Element("nameCampaign") nameCampaign.text = name_campaign_sql.decode("utf-8") campaign.append(nameCampaign) x_step = Element("x_step") x_step.text = str(x_step_campaign_sql).decode("utf-8") campaign.append(x_step) y_step = Element("y_step") y_step.text = str(y_step_campaign_sql).decode("utf-8") campaign.append(y_step) z_step = Element("z_step") z_step.text = str(z_step_campaign_sql).decode("utf-8") campaign.append(z_step) date = Element("date") date.text = str(date_campaign_sql).decode("utf-8") campaign.append(date) eperf_parameters = Element("eperf_parameters") if eperf_parameters_campaign_sql: address_server, port_server, measure_time_eperf, interval_time_eperf, name_protocol_eperf, packet_size_eperf, rate_eperf, connectionTCP, directionUpOrDown = re.split(';', eperf_parameters_campaign_sql) #EPERF_PARAMETERS arguments add_server = Element("server_address") add_server.text = str(address_server).decode("utf-8") eperf_parameters.append(add_server) p_server = Element("server_port") p_server.text = port_server.decode("utf-8") eperf_parameters.append(p_server) measure_time = Element("measure_time") measure_time.text = measure_time_eperf.decode("utf-8") eperf_parameters.append(measure_time) interval_time = Element("time_interval") interval_time.text = str(interval_time_eperf).decode("utf-8") eperf_parameters.append(interval_time) protocol = Element("protocol") #PROTOCOL arguments name = Element("name") name.text = name_protocol_eperf.decode("utf-8") protocol.append(name) direction = Element("direction") direction.text = str(directionUpOrDown).decode("utf-8") protocol.append(direction) packet_size = Element("packet_size") packet_size.text = str(packet_size_eperf).decode("utf-8") protocol.append(packet_size) rate = Element("rate_UDP") rate.text = str(rate_eperf).decode("utf-8") protocol.append(rate) connection = Element("connection_TCP") connection.text = str(connectionTCP).decode("utf-8") protocol.append(connection) eperf_parameters.append(protocol) campaign.append(eperf_parameters) #Loop on the AP self.__ap_list(campaign, id_campaign) #Loop on the measures self.__measure(campaign, id_campaign) place.append(campaign) def __ap_list(self, campaign, id_campaign): """ The function '__ap_list()' permit writting XML file for the part of AP list :argument campaign (type Element) Top tag id_place (type Int) place number id_campaign (type Int) campaign number """ aps = Element("aps") #Loop through the user selected APs for id_ap_user in self.id_ap: #Queries SQL AP configuration ap_conf = self.db.select('ap_configuration',\ [ 'channel', 'encryption', 'standard'],\ {'id_campaign':id_campaign,'id_ap':id_ap_user}); #Loop on the APs of the campaign for channel_ap_conf_sql, encryption_ap_conf_sql, standard_ap_conf_sql in ap_conf: #Queries SQL AP req_sql = self.db.select('ap',\ ['essid', 'mac_address','x_coordinate_place', 'y_coordinate_place', 'z_coordinate_place', 'description'], {'id_ap':id_ap_user}) essid_ap_sql,mac_address_ap_conf_sql, x_coordinate_place_ap_sql, y_coordinate_place_ap_sql, z_coordinate_place_ap_sql, description_ap_sql = req_sql[0] #Tag AP ap = Element("ap") #AP arguments macAddress_Ap = Element("macAddress_Ap") macAddress_Ap.text = mac_address_ap_conf_sql.decode("utf-8") ap.append(macAddress_Ap) essid_Ap = Element("essid_Ap") essid_Ap.text = essid_ap_sql.decode("utf-8") ap.append(essid_Ap) x_coordinate_place_Ap = Element("x_coordinate_place_Ap") x_coordinate_place_Ap.text = str(x_coordinate_place_ap_sql).decode("utf-8") ap.append(x_coordinate_place_Ap) y_coordinate_place_Ap = Element("y_coordinate_place_Ap") y_coordinate_place_Ap.text = str(y_coordinate_place_ap_sql).decode("utf-8") ap.append(y_coordinate_place_Ap) z_coordinate_place_Ap = Element("z_coordinate_place_Ap") z_coordinate_place_Ap.text = str(z_coordinate_place_ap_sql).decode("utf-8") ap.append(z_coordinate_place_Ap) #Recovery of the global coordinates x_coordinate_area_place_trans, y_coordinate_area_place_trans, z_coordinate_area_place_trans = self.trans_g.localToGlobal(x_coordinate_place_ap_sql, y_coordinate_place_ap_sql, z_coordinate_place_ap_sql) x_coordinate_area_Ap = Element("x_coordinate_area_Ap") x_coordinate_area_Ap.text = str(int(x_coordinate_area_place_trans)).decode("utf-8") ap.append(x_coordinate_area_Ap) y_coordinate_area_Ap = Element("y_coordinate_area_Ap") y_coordinate_area_Ap.text = str(int(y_coordinate_area_place_trans)).decode("utf-8") ap.append(y_coordinate_area_Ap) z_coordinate_area_Ap = Element("z_coordinate_area_Ap") z_coordinate_area_Ap.text = str(int(z_coordinate_area_place_trans)).decode("utf-8") ap.append(z_coordinate_area_Ap) channel_Ap = Element("channel_Ap") channel_Ap.text = str(channel_ap_conf_sql).decode("utf-8") ap.append(channel_Ap) encryption_Ap = Element("encryption_Ap") encryption_Ap.text = str(encryption_ap_conf_sql).decode("utf-8") ap.append(encryption_Ap) description_Ap = Element("description_Ap") description_Ap.text = description_ap_sql.decode("utf-8") ap.append(description_Ap) #Add AP in APS aps.append(ap) campaign.append(aps) def __measure(self, campaign, id_campaign): """ The function '__measure()' permit writting XML file for the part of measures :argument: campaign (type Element) Top tag id_campaign (type Int) Campaign number """ measures = Element("measures") #Loop through the user selected APs for id_ap_user in self.id_ap: #Queries SQL measures measure_list = self.db.select('measure',\ ['id_measure','id_ap','x_coordinate_place','y_coordinate_place','z_coordinate_place','signal_level','noise_level','bitrate_level2','rate_level4','timestamp'],\ {'id_campaign':id_campaign,'id_ap':id_ap_user}) #loop on the measure for id_measure_measure_sql, id_ap_measure_sql, x_coordinate_place_measure_sql, y_coordinate_place_measure_sql, z_coordinate_place_measure_sql, signal_level_measure_sql,\ noise_level_measure_sql, bitrate_level2_measure_sql, rate_level4_measure_sql, timestamp_measure_sql in measure_list: #tag MEASURE measure = Element("measure") #MEASURE Arguments timestamp = Element("timestamp") timestamp.text = timestamp_measure_sql.decode("utf-8") measure.append(timestamp) macAddress_measure = Element("macAddress_measure") macAddress_measure.text = str(self.db.select('ap','mac_address',{'id_ap':id_ap_measure_sql})[0][0]).decode("utf-8") #macAddress_measure.text = mac_address_measure_sql.decode("utf-8").decode("utf-8") measure.append(macAddress_measure) x_coordinate_place = Element("x_coordinate_place") x_coordinate_place.text = str(x_coordinate_place_measure_sql).decode("utf-8") measure.append(x_coordinate_place) y_coordinate_place = Element("y_coordinate_place") y_coordinate_place.text = str(y_coordinate_place_measure_sql).decode("utf-8") measure.append(y_coordinate_place) z_coordinate_place = Element("z_coordinate_place") z_coordinate_place.text = str(z_coordinate_place_measure_sql).decode("utf-8") measure.append(z_coordinate_place) #Recovery of the global coordinates x_coordinate_area_place_trans, y_coordinate_area_place_trans, z_coordinate_area_place_trans = self.trans_g.localToGlobal(x_coordinate_place_measure_sql, y_coordinate_place_measure_sql, z_coordinate_place_measure_sql) x_coordinate_global = Element("x_coordinate_global") x_coordinate_global.text = str(int(x_coordinate_area_place_trans)).decode("utf-8") measure.append(x_coordinate_global) y_coordinate_global = Element("y_coordinate_global") y_coordinate_global.text = str(int(y_coordinate_area_place_trans)).decode("utf-8") measure.append(y_coordinate_global) z_coordinate_global = Element("z_coordinate_global") z_coordinate_global.text = str(int(z_coordinate_area_place_trans)).decode("utf-8") measure.append(z_coordinate_global) noise_level = Element("noise_level") noise_level.text = str(noise_level_measure_sql).decode("utf-8") measure.append(noise_level) signal_level_measure = Element("signal_level_measure") signal_level_measure.text = str(signal_level_measure_sql).decode("utf-8") measure.append(signal_level_measure) bit_rate_level = Element("bit_rate_level") bit_rate_level.text = str(bitrate_level2_measure_sql).decode("utf-8") measure.append(bit_rate_level) rate_level = Element("rate_level") rate_level.text = str(rate_level4_measure_sql).decode("utf-8") measure.append(rate_level) environment = Element("environment") #Loop on the disturbing detected AP self.__disturbing_ap(environment,id_measure_measure_sql) measure.append(environment) #Add MEASURE in MEASURES measures.append(measure) campaign.append(measures) def __disturbing_ap(self, environment, id_measure): """ The function '__write_disturbing_ap()' permit writting XML file for the part of disturbing_ap :argument: environment (type Element) Top tag id_measure (type Int) Measure number """ #Creation of the SQL queries result_disturbing_ap = self.db.select('disturbing_ap',\ ['essid', 'mac_address', 'channel', 'encryption', 'protocol', 'signal_level'],\ {'id_measure':id_measure}) #Loop on the disturbing detected AP for essid_sql, mac_address_sql, channel_sql, encryption_sql, protocol_sql, signal_level_sql in result_disturbing_ap : #TagDISTURBING_AP disturbing_ap = Element("disturbing_ap") #DISTURBING_AP Arguments macAddress = Element("macAddress") macAddress.text = mac_address_sql.decode("utf-8") disturbing_ap.append(macAddress) essid = Element("essid") essid.text = essid_sql.decode("utf-8") disturbing_ap.append(essid) channel = Element("channel") channel.text = str(channel_sql).decode("utf-8") disturbing_ap.append(channel) encryption = Element("encryption") encryption.text = encryption_sql.decode("utf-8") disturbing_ap.append(encryption) signal_level = Element("signal_level") signal_level.text = str(signal_level_sql).decode("utf-8") disturbing_ap.append(signal_level) #Add of DISTURBING_AP in ENVIRONMENT environment.append(disturbing_ap) def __prettyprint(self, root, level=0): """ The function '__prettyprint' used to indent the output in a format xml :argument: element (type Element) choice of root indent This function must be called before writing to a file """ i = "\n" + level*" " if len(root): if not root.text or not root.text.strip(): root.text = i + " " if not root.tail or not root.tail.strip(): root.tail = i for child in root: self.__prettyprint(child, level+1) if not child.tail or not child.tail.strip(): child.tail = i if not root.tail or not root.tail.strip(): root.tail = i else: if level and (not root.tail or not root.tail.strip()): root.tail = i def __format_sql_result(self, result_sql): """ The function '__format_sql_result' used to format string as the result of an SQL query. By default, the result of an SQL query is a list of list This function is required for the creation of Element or SubElement """ result_sql = result_sql[0] liste_temp = [] for row in result_sql: liste_temp.append(str(row)) return liste_temp
[docs] def toPNG(self,resolution=100, legende=True, amplitude=''): """ The function 'toXML' to extract information from the BDD in a PNG file :arguments optionels: resolution (type integer) You can choose the resolution of the drawing. By default it is 50 legende (type Boolean) Adds legend drawing, otherwise returns the surface amplitude (type integer) Allows you to choose which power ranges are defined colors :return: . png file created on the current directory """ #Recovery information in the DB to create the image file lieux_taille = self.db.select(['campaign','place','area'],\ ['place.length','place.width', 'area.name', 'place.name', 'campaign.name', 'campaign.date'],\ {'campaign.id_campaign':self.id_campaigne,'place.id_place':'campaign.id_place', 'place.id_area':'area.id_area'}) width, height, batiment, lieux, campagne, date = lieux_taille[0] width_pix, height_pix = [val*resolution for val in [width, height]] #Creation of file self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width_pix, height_pix) self.context = cairo.Context(self.surface) self.context.scale(self.surface.get_width(),self.surface.get_height()) self.context.set_source_rgb(1, 1, 1) self.context.paint() #Recovery of steps to calculate the number of points to create the points step_x, step_y = self.db.select('campaign',['x_step','y_step'], {'id_campaign':self.id_campagne})[0] if width > height: rayon = (float(resolution) / height_pix)*1.5 else: rayon = (float(resolution) / width_pix)*1.5 if not amplitude: amplitude = FindAmplitude(self.id_campagne).get() #Recovery of all steps of the campaign mesures = self.db.select('measure',['x_coordinate_place','y_coordinate_place', 'signal_level'],{'id_campaign':self.id_campagne}) #Creation points for mesure in mesures: #define color red, green, blue = FloatRgbMulti(mesure[2],amplitude[0],amplitude[1]).get() self.context.save() #We define two circles x, y, with different radius and a color effect y = (height-(height-mesure[1])) / float(height) x=mesure[0] self.context.scale(height/float(width),1) radial = cairo.RadialGradient(x/float(height), y, rayon*0.1, x/float(height), y, rayon) radial.add_color_stop_rgba(0, 0, 0, 0, 1) radial.add_color_stop_rgba(0.7, 0, 0, 0, 0) self.context.set_source_rgb(red, green, blue) self.context.mask(radial) self.context.restore() #If we add a caption to the drawing if legende: if width_pix >= height_pix: #It gets the largest side to: leg_x, leg_y = width_pix, 0 #-position the legend so large drawing, we put the caption on the right, if not lower. maximum = width_pix #-define the size of the legend (20% of the largest side width_pix *= 1.2 else: leg_x, leg_y = 0, height_pix maximum = height_pix height_pix *= 1.2 #Creation of the legend with four information placed in the list (argument 1), #Recuperation des steps afin de calculer le nombre de point à créer les points #the minimum and maximum values ​​used for coloring (argument 2 & 3), and the size of the largest side (argument 4) surface_legende = Legende( [('Batiment',batiment),('Lieux',lieux),('Campagne',campagne),('Date',date)],\ amplitude[0], amplitude[1], maximum).get() #We recreate a large surface + to paste the drawing + legend on a white background surface_with_legende = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width_pix), int(height_pix)) context = cairo.Context(surface_with_legende) context.set_source_rgb(1, 1, 1) context.paint() #Collage drawing context.set_source_surface(self.surface, 0, 0) context.paint() #Collage of the legend context.set_source_surface(surface_legende, leg_x, leg_y) context.paint() #Write File surface_with_legende.write_to_png(self.fichier+'.png') else:#Otherwise it returns the surface in order to use the design return self.surface
[docs]class FloatRgbMulti: """ The class 'FloatRgbMulti' sets the range of colors that will be applied on the graph. It provided a color depending on mag between cmin et cmax. :arguments: mag (type integer) Choice of the magnitude cmin (type integer) Choosing the minimum value that will be represented by a color cmax (type integer) Choice of max will be represented by a color :couleurs: Warm color for high values(rouge) Cool color for low values(bleu ciel) :return: Tuple as (reg, green, blue) """ def __init__(self, mag, cmin, cmax): #normalization with respect to mag cmin and cmax try: x = float(mag-cmin)/float(cmax-cmin) #case of division by 0 except: if mag == cmin: x = 0.5 #definition d' 1/3 tiers = 1/float(3) #Algo: #To vary the colors we can divide the process into three parts (or third) #A variation of the green, then red and finally blue each time between 1.0 and 0.0 #We look for what is our third value #then renormalize this value to know what is the corresponding intensity if x >= 1.5*tiers: self.red = 1 self.green = 1-(x-(2*tiers))/tiers self.blue = 0 elif x <= 0.8*tiers: self.red = 0 self.green = 1 self.blue = 1-(x / tiers) else: self.red = (x-tiers)/(2*tiers) self.green = 1 self.blue = 0
[docs] def get(self): """ This function retrieves the color code """ return (self.red, self.green, self.blue)
[docs]class FindAmplitude: """ To find the amplitude was applied to a extract.PNG () to one or more campaign! """ def __init__(self, id_campagnes): liste_id_campagne=[] all_mesure=[] db = DBA.DBConnect() if type(id_campagnes) == int: liste_id_campagne.append(id_campagnes) else: liste_id_campagne = id_campagnes for id_campagne in liste_id_campagne: mesures = db.select('measure',['signal_level'],{'id_campaign':id_campagne},('signal_level','DESC')) for mesure in mesures: all_mesure.append(mesure[0]) max_power = -100 min_power = 0 power_liste_clean=[] #it gets the max and min values ​​measured outside the -100 to 0 to find the amplitude measures for power in all_mesure: if power < 0 and power > max_power: max_power = power elif power > -100 and power < min_power: min_power = power if power < 0 and power > -100: power_liste_clean.append(power) amplitude_temp=max_power-min_power #it gets the max and min values ​​measured outside the -100 to 0 to find the amplitude measures somme = 0 for power in power_liste_clean: somme += power moyenne= somme / len(power_liste_clean) #It was decided that the range of values ​​for the drawing is equal to the average + or - 80% of the amplitude self.amplitude = (moyenne-amplitude_temp*0.3, moyenne+amplitude_temp*0.5) def get(self): return self.amplitude
[docs]class DessinBatiment: """ Can be extracted into a PNG, the results of a set of campaign :arguments: - liste_id_campagne (type list) List with the numbers of campaign we want to show - fichier (type string) Selecting the name of the file extraction, is extansion. Png is added automatically - resolution (type integer) Optional parameter to adjust the resolution in pixels per meter. (default = 100) **exemple** >>> liste_id_campagne = [1,2,3,4] >>> file = 'essai_extract' dessinBatiment(liste_id_campagne,fichier, 100) """ def __init__(self, liste_id_campagne, fichier='DessinBatiment', resolution=100): width = height = 0 coor_list = [] #Recovery of the name of the building for the legend batiment = DBA.DBConnect().select(['area', 'place', 'campaign'],\ ['area.name'],\ {'campaign.id_campaign' : liste_id_campagne[0],\ 'campaign.id_place':'place.id_place',\ 'place.id_area':'area.id_area'})[0][0] #To set the final file size is sought for each of the campaigns #max-value of the coordinate of the part + length on two axes #backup-coordinates of the rooms in a list to see where glue surfaces for id_campagne in liste_id_campagne: resultat = DBA.DBConnect().select(['campaign','place'],\ ['campaign.id_place','x_coordinate_area','y_coordinate_area','widht','length'],\ {'campaign.id_place':'place.id_place', 'campaign.id_campaign':id_campagne})[0] if width < resultat[1] + resultat[4]: width = resultat[1] + resultat[4] if height < resultat[2] + resultat[3]: height = resultat[2] + resultat[3] coor_list.append((resultat[1]*resolution,resultat[2]*resolution)) width_pix = width*resolution height_pix = height*resolution #Same algorithm as for adding a legend in extract.toPNG () if width_pix >= height_pix: leg_x, leg_y = width_pix, 0 maximum = width_pix width_pix *= 1.2 else: leg_x, leg_y = 0, height_pix maximum = height_pix height_pix *= 1.2 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width_pix), int(height_pix)) context = cairo.Context(surface) context.set_source_rgb(1, 1, 1) context.paint() #Search the magnitude of pattern based on all campaigns amplitude = FindAmplitude(liste_id_campagne).get() #Generate the surface for each of the campaigns and pasting on the final design compteur = 0 for id_campagne in liste_id_campagne: surface_temp = Extract(id_campagne, "useless").toPNG(resolution, False, amplitude) context.set_source_surface(surface_temp, coor_list[compteur][0], coor_list[compteur][1]) context.paint() compteur += 1 #Generate the surface legend and paste surface_legende = Legende( [('Batiment',batiment)], amplitude[0], amplitude[1], maximum).get() context.set_source_surface(surface_legende, leg_x, leg_y) context.paint() #Write files surface.write_to_png(fichier+'.png')
[docs]class Legende: """ Generates the surface corresponding to the caption of a drawing :arguments: - informations (type list) List of tuple, where each tuple contains the name of information and information - power_min (type int) Min power used for the color of the drawing - power_max (type int) Max power used for the color of the drawing - size the pixel size of the largest side of the drawing **exemple** >>> amplitude = FindAmplitude(numerodecampagne).get() >>> leg = Legende([('Batiment','Maison'),('Pièce','Chambre'),('Campagne','Première'),('Date','17/11/85')],amplitudetest[0], amplitudetest[1], 2100).get() extract(numerodecampagne,'testaveclegende').toPNG(100) """ def __init__(self, informations, power_min, power_max, size): #The base area of a size self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(size*0.2), int(size*0.2)) context = cairo.Context(self.surface) context.set_source_rgb(1, 1, 1) context.paint() self.reference = size*0.2 #variable used to rescale the function dynamically place the elements of the legend #All values ​​below are referenced on a matrix 1 / 1 (a square of side 1) #rescale the function multiplies the reference values ​​to adapt the result #Creation of the rectangle with the gradient context.rectangle(self.rescale(0.85),self.rescale(0.15),self.rescale(0.125),self.rescale(0.8)) #x, y, largeur, hauteur ligne = cairo.LinearGradient(self.rescale(0.5), self.rescale(0.15), self.rescale(0.5), self.rescale(0.9)) #pour la colorisation #creation of 10 points in the gradient colors for i in range(10,0,-1): r, g, b = FloatRgbMulti(i, 1, 10).get() ligne.add_color_stop_rgba(1-i*0.1, r, g, b, 1) context.set_source(ligne) context.fill() #Creating the Legend title context.set_source_rgb(0,0,0) context.select_font_face("Georgia", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) context.set_font_size(self.rescale(0.10)) context.move_to(self.rescale(0.27), self.rescale(0.1) ) context.show_text("Légende") #Creation of values ​​at the ends of the rectangle context.set_font_size(self.rescale(0.05)) context.select_font_face("Georgia", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) context.move_to(self.rescale(0.65),self.rescale(0.2)) context.show_text(str(int(power_max))+'dB') context.move_to(self.rescale(0.65),self.rescale(0.925)) context.show_text(str(int(power_min))+'dB') #Creating titles and information level = self.rescale(0.2) for info in informations: context.move_to(self.rescale(0.05),level) context.select_font_face("Georgia", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) context.show_text("%s :" % info[0]) context.move_to(self.rescale(0.075), level+self.rescale(0.05)) context.select_font_face("Georgia", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) context.show_text(info[1]) level += self.rescale(0.2)
[docs] def get(self): """ reference surface with the legend """ return self.surface
[docs] def rescale(self, x): """ Customize the text and the forms of the legend according to the size of the final image """ return x*self.reference
if __name__=="__main__": #amplitudetest = FindAmplitude(151).get() #leg = Legende( [('Batiment','Maison'), ('Pièce','Chambre'), ('Campagne','Première'), ('Date','17/11/85')], amplitudetest[0], amplitudetest[1], 2100).get() #Extract(151,'testaveclegende').toPNG(100, leg) #DessinBatiment([151,152]) #Extract(151,'Premiere').toXML() Extract(1,[1],[1,2,3],1,'Premiere').toXML()