def calcall(self):
        fr_d_t = self.FromDateTime.dateTime().toPyDateTime()
        to_d_t = self.ToDateTime.dateTime().toPyDateTime()
        
#        sanity1 = utils.sql_load_fr_db("""SELECT obs_points.h_toc FROM obs_points LEFT JOIN w_levels WHERE w_levels.obsid = obs_points.obsid AND obs_points.h_toc""")[1]
        sanity1 = utils.sql_load_fr_db("""SELECT obs_points.h_toc FROM obs_points LEFT JOIN w_levels WHERE w_levels.obsid = obs_points.obsid""")[1]
        sanity2 = utils.sql_load_fr_db("""SELECT obs_points.h_toc FROM obs_points LEFT JOIN w_levels WHERE w_levels.obsid = obs_points.obsid AND obs_points.h_toc NOT NULL""")[1]
        
        if len(sanity1) == len(sanity2): #only if h_toc exists for all objects!!
            sql1 = """UPDATE OR IGNORE w_levels SET h_toc = (SELECT obs_points.h_toc FROM obs_points WHERE w_levels.obsid = obs_points.obsid) WHERE """
            sql1 += """date_time >= '"""
            sql1 += str(fr_d_t)
            sql1 += """' AND date_time <= '"""
            sql1 += str(to_d_t)
            sql1 += """' """
            utils.sql_alter_db(sql1)
            sql2 = """UPDATE OR IGNORE w_levels SET level_masl = h_toc - meas WHERE """
            sql2 += """date_time >= '"""
            sql2 += str(fr_d_t)
            sql2 += """' AND date_time <= '"""
            sql2 += str(to_d_t)
            sql2 += """' """        
            utils.sql_alter_db(sql2)
            self.close()
        else:
            utils.pop_up_info('Calculation aborted! There seems to be NULL values in your table obs_points, column h_toc.','Error')
            self.close()
 def calibrateandplot(self):
     obsid = unicode(self.combobox_obsid.currentText())
     if not obsid=='':
         sanity1sql = """select count(obsid) from w_levels_logger where obsid = '""" +  obsid[0] + """'"""
         sanity2sql = """select count(obsid) from w_levels_logger where head_cm not null and head_cm !='' and obsid = '""" +  obsid[0] + """'"""
         if utils.sql_load_fr_db(sanity1sql)[1] == utils.sql_load_fr_db(sanity2sql)[1]: # This must only be done if head_cm exists for all data
             fr_d_t = self.FromDateTime.dateTime().toPyDateTime()
             to_d_t = self.ToDateTime.dateTime().toPyDateTime()
             newzref = self.LoggerPos.text()
             if len(newzref)>0:
                 sql =r"""UPDATE w_levels_logger SET level_masl = """
                 sql += str(newzref)
                 sql += """ + head_cm / 100 WHERE obsid = '"""
                 sql += obsid   
                 sql += """' AND date_time >= '"""
                 sql += str(fr_d_t)
                 sql += """' AND date_time <= '"""
                 sql += str(to_d_t)
                 sql += """' """
                 dummy = utils.sql_alter_db(sql)
             self.CalibrationPlot(obsid)
             self.getlastcalibration()
         else:
             utils.pop_up_info("Calibration aborted!!\nThere must not be empty cells or\nnull values in the 'head_cm' column!")
     else:
         self.INFO.setText("Select the observation point with logger data to be calibrated.")
Esempio n. 3
0
    def settings_strings_dialogs(self):

        msg = ru(
            QCoreApplication.translate(
                u'ExportToFieldLogger',
                u'Edit the settings string for input fields browser and restart export fieldlogger dialog\nto load the change.'
            ))
        browser_updated = self.ask_and_update_settings(
            [self.parameter_browser], self.stored_settingskey_parameterbrowser,
            msg)
        msg = ru(
            QCoreApplication.translate(
                u'ExportToFieldLogger',
                u'Edit the settings string for input fields groups and restart export fieldlogger dialog\nto load the change.'
            ))
        groups_updated = self.ask_and_update_settings(self.parameter_groups,
                                                      self.stored_settingskey,
                                                      msg)
        if browser_updated or groups_updated:
            utils.pop_up_info(
                ru(
                    QCoreApplication.translate(
                        u'ExportToFieldLogger',
                        u'Settings updated. Restart Export to Fieldlogger dialog\nor press "Save settings" to undo.'
                    )))
    def calcselected(self):
        obsar = utils.getselectedobjectnames(self.layer)
        observations = obsar
        i=0
        for obs in obsar:
                observations[i] = obs.encode('utf-8') #turn into a list of python byte strings
                i += 1        
        fr_d_t = self.FromDateTime.dateTime().toPyDateTime()
        to_d_t = self.ToDateTime.dateTime().toPyDateTime()

        sanity1 = utils.sql_load_fr_db("""SELECT obs_points.h_toc FROM obs_points LEFT JOIN w_levels WHERE w_levels.obsid = obs_points.obsid AND obs_points.obsid IN """ + (str(observations)).encode('utf-8').replace('[','(').replace(']',')'))[1]
        sanity2 = utils.sql_load_fr_db("""SELECT obs_points.h_toc FROM obs_points LEFT JOIN w_levels WHERE w_levels.obsid = obs_points.obsid AND obs_points.h_toc NOT NULL  AND obs_points.obsid IN """ + (str(observations)).encode('utf-8').replace('[','(').replace(']',')'))[1]

        if len(sanity1) == len(sanity2): #only if h_toc exists for all objects
            sql1 = """UPDATE OR IGNORE w_levels SET h_toc = (SELECT obs_points.h_toc FROM obs_points WHERE w_levels.obsid = obs_points.obsid) WHERE obsid IN """
            sql1 += str(observations)
            sql1 += """ AND date_time >= '"""
            sql1 += str(fr_d_t)
            sql1 += """' AND date_time <= '"""
            sql1 += str(to_d_t)
            sql1 += """' """   
            utils.sql_alter_db(sql1.replace("[","(").replace("]",")"))
            sql2 = """UPDATE OR IGNORE w_levels SET level_masl = h_toc - meas WHERE obsid IN """
            sql2 += str(observations)
            sql2 += """ AND date_time >= '"""
            sql2 += str(fr_d_t)
            sql2 += """' AND date_time <= '"""
            sql2 += str(to_d_t)
            sql2 += """' """        
            utils.sql_alter_db(sql2.replace("[","(").replace("]",")"))
            self.close()        
        else:
            utils.pop_up_info('Calculation aborted! There seems to be NULL values in your table obs_points, column h_toc.','Error')
            self.close()
    def calculate_offset(self):
        """ Part of adjustment method 3. adjust level_masl by clicking in plot.
        this method extracts the head from head_ts with the same date as the line node.
            4. Calculating y-position - head (or level_masl) and setting self.LoggerPos.
            5. Run calibration.
        """            
        if self.log_pos is not None and self.y_pos is not None:
            utils.start_waiting_cursor()

            logger_ts = self.level_masl_ts
            
            y_pos = self.y_pos
            log_pos = self.log_pos
            self.y_pos = None
            self.log_pos = None
            log_pos_date = datestring_to_date(log_pos).replace(tzinfo=None)
            logger_value = None

            #Get the value for the selected node
            for raw_date, logger_value in logger_ts:
                date = datestring_to_date(raw_date).replace(tzinfo=None)
                if date == log_pos_date:
                    break

            if logger_value is None:
                utils.pop_up_info(ru(QCoreApplication.translate('Calibrlogger', "No connection between level_masl dates and logger date could be made!\nTry again or choose a new logger line node!")))
            else:
                self.Add2Levelmasl.setText(str(float(y_pos) - float(logger_value)))

                utils.stop_waiting_cursor()

        self.pushButtonMpos.setEnabled(False)
    def calc_best_fit(self):
        """ Calculates the self.LoggerPos from self.meas_ts and self.head_ts
        
            First matches measurements from self.meas_ts to logger values from
            self.head_ts. This is done by making a mean of all logger values inside
            self.meas_ts date - tolerance and self.meas_ts date + tolerance.
            (this could probably be change to get only the closest logger value
            inside the tolerance instead)
            (Tolerance is gotten from self.get_tolerance())
            
            Then calculates the mean of all matches and set to self.LoggerPos.
        """
        obsid = self.load_obsid_and_init()
        self.reset_plot_selects_and_calib_help()
        tolerance = self.get_tolerance()
        really_calibrate_question = utils.askuser("YesNo", """This will calibrate all values inside the chosen period\nusing the mean difference between logger values and measurements.\n\nTime tolerance for matching logger and measurement nodes set to '""" + ' '.join(tolerance) + """'\n\nContinue?""")
        if really_calibrate_question.result == 0: # if the user wants to abort
            return

        PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor)
        if self.loggerpos_masl_or_offset_state == 1:
            logger_ts = self.head_ts
        else:
            logger_ts = self.level_masl_ts



        coupled_vals = self.match_ts_values(self.meas_ts, logger_ts, tolerance)
        if not coupled_vals:
            utils.pop_up_info("There was no matched measurements or logger values inside the chosen period.\n Try to increase the tolerance!")
        else:            
            self.LoggerPos.setText(str(utils.calc_mean_diff(coupled_vals)))
            self.calibrateandplot()
        PyQt4.QtGui.QApplication.restoreOverrideCursor()
Esempio n. 7
0
 def showSurvey(self):
     #lyr = self.iface.activeLayer() # THIS IS TSPLOT-method, GETS THE SELECTED LAYER
     lyr = self.layer
     ids = lyr.selectedFeaturesIds()
     if len(ids) == 0:
         utils.pop_up_info(
             ru(
                 QCoreApplication.translate(u' Stratigraphy',
                                            u"No selection")),
             ru(
                 QCoreApplication.translate(u' Stratigraphy',
                                            u"No features are selected")))
         return
     # initiate the datastore if not yet done
     self.initStore()
     PyQt4.QtGui.QApplication.setOverrideCursor(
         PyQt4.QtCore.Qt.WaitCursor)  # Sets the mouse cursor to wait symbol
     try:  # return from store.getData is stored in data only if no object belonging to DataSanityError class is created
         self.data = self.store.getData(ids,
                                        lyr)  # added lyr as an argument!!!
     except DataSanityError, e:  # if an object 'e' belonging to DataSanityError is created, then do following
         print("DataSanityError %s" % str(e))
         PyQt4.QtGui.QApplication.restoreOverrideCursor()
         utils.pop_up_info(
             ru(
                 QCoreApplication.translate(
                     u' Stratigraphy',
                     u"Data sanity problem, obsid: %s\n%s")) %
             (e.sond_id, e.message))
         return
Esempio n. 8
0
    def __init__(self, obsids=[''], settingsdict = {}):

        reportfolder = os.path.join(QDir.tempPath(), 'midvatten_reports')
        if not os.path.exists(reportfolder):
            os.makedirs(reportfolder)
        reportpath = os.path.join(reportfolder, "drill_report.html")
        logopath = os.path.join(os.sep,os.path.dirname(__file__),"..","templates","midvatten_logga.png")
        imgpath = os.path.join(os.sep,os.path.dirname(__file__),"..","templates")

        if len(obsids) == 0:
            utils.pop_up_info(ru(QCoreApplication.translate('Drillreport', "Must select one or more obsids!")))
            return None
        elif len(obsids) == 1:
            merged_question = False
        else:
            #Due to problems regarding speed when opening many tabs, only the merge mode is used.
            #merged_question = utils.Askuser(question='YesNo', msg="Do you want to open all drill reports merged on the same tab?\n"
            #                                    "Else they will be opened separately.\n\n(If answering no, creating drill reports for many obsids take 0.2 seconds per obsid.\nIt might fail if the computer is to slow.\nIf it fails, try to select only one obsid at the time)").result
            merged_question = True

        if merged_question:
            f, rpt = self.open_file(', '.join(obsids), reportpath)
            for obsid in obsids:
                self.write_obsid(obsid, rpt, imgpath, logopath, f)
            self.close_file(f, reportpath)
        else:
            #opened = False
            for obsid in obsids:
                f, rpt = self.open_file(obsid, reportpath)
                self.write_obsid(obsid, rpt, imgpath, logopath, f)
                url_status = self.close_file(f, reportpath)
 def showSurvey(self):
     #lyr = self.iface.activeLayer() # THIS IS TSPLOT-method, GETS THE SELECTED LAYER
     lyr = self.layer
     ids = lyr.selectedFeatureIds()
     if len(ids) == 0:
         utils.pop_up_info(ru(QCoreApplication.translate(' Stratigraphy', "No selection")), ru(QCoreApplication.translate(' Stratigraphy', "No features are selected")))
         return
     # initiate the datastore if not yet done   
     self.initStore()   
     utils.start_waiting_cursor()  # Sets the mouse cursor to wait symbol
     try:  # return from store.getData is stored in data only if no object belonging to DataSanityError class is created
         self.data = self.store.getData(ids, lyr)    # added lyr as an argument!!!
     except DataSanityError as e: # if an object 'e' belonging to DataSanityError is created, then do following
         print("DataSanityError %s"%str(e))
         utils.stop_waiting_cursor()
         utils.pop_up_info(ru(QCoreApplication.translate(' Stratigraphy', "Data sanity problem, obsid: %s\n%s")) % (e.sond_id, e.message))
         return
     except Exception as e: # if an object 'e' belonging to DataSanityError is created, then do following
         print("exception : %s"%str(e))
         utils.stop_waiting_cursor()
         utils.MessagebarAndLog.critical(bar_msg=ru(QCoreApplication.translate(' Stratigraphy', "The stratigraphy plot failed, check Midvatten plugin settings and your data!")))
         return
     utils.stop_waiting_cursor()  # Restores the mouse cursor to normal symbol
     # show widget
     w = SurveyDialog()
     #w.widget.setData2_nosorting(data)  #THIS IS IF DATA IS NOT TO BE SORTED!!
     w.widget.setData(self.data)  #THIS IS ONLY TO SORT DATA!!
     w.show()
     self.w = w # save reference so it doesn't get deleted immediately        This has to be done both here and also in midvatten instance
    def delete_selected_range(self, table_name):
        """ Deletes the current selected range from the database from w_levels_logger
        :return: De
        """
        current_loaded_obsid = self.obsid
        selected_obsid = self.load_obsid_and_init()
        if current_loaded_obsid != selected_obsid:
            utils.pop_up_info(ru(QCoreApplication.translate('Calibrlogger', "Error!\n The obsid selection has been changed but the plot has not been updated. No deletion done.\nUpdating plot.")))
            self.update_plot()
            return
        elif selected_obsid is None:
            utils.pop_up_info(ru(QCoreApplication.translate('Calibrlogger', "Error!\n No obsid was selected. No deletion done.\nUpdating plot.")))
            self.update_plot()
            return

        fr_d_t = str((self.FromDateTime.dateTime().toPyDateTime() - datetime.datetime(1970,1,1)).total_seconds())
        to_d_t = str((self.ToDateTime.dateTime().toPyDateTime() - datetime.datetime(1970,1,1)).total_seconds())

        sql_list = []
        sql_list.append(r"""DELETE FROM "%s" """%table_name)
        sql_list.append(r"""WHERE obsid = '%s' """%selected_obsid)
        # This %s is db formatting for seconds. It is not used as python formatting!
        sql_list.append(r"""AND CAST(strftime('%s', date_time) AS NUMERIC) """)
        sql_list.append(r""" > '%s' """%fr_d_t)
        # This %s is db formatting for seconds. It is not used as python formatting!
        sql_list.append(r"""AND CAST(strftime('%s', date_time) AS NUMERIC) """)
        sql_list.append(r""" < '%s' """%to_d_t)
        sql = ''.join(sql_list)

        really_delete = utils.Askuser("YesNo", ru(QCoreApplication.translate('Calibrlogger', "Do you want to delete the period %s to %s for obsid %s from table %s?"))%(str(self.FromDateTime.dateTime().toPyDateTime()), str(self.ToDateTime.dateTime().toPyDateTime()), selected_obsid, table_name)).result
        if really_delete:
            utils.start_waiting_cursor()
            db_utils.sql_alter_db(sql)
            utils.stop_waiting_cursor()
            self.update_plot()
    def delete_selected_range(self, table_name):
        """ Deletes the current selected range from the database from w_levels_logger
        :return: De
        """
        current_loaded_obsid = self.obsid
        selected_obsid = self.load_obsid_and_init()
        if current_loaded_obsid != selected_obsid:
            utils.pop_up_info("Error!\n The obsid selection has been changed but the plot has not been updated. No deletion done.\nUpdating plot.")
            self.update_plot()
            return

        fr_d_t = str((self.FromDateTime.dateTime().toPyDateTime() - datetime.datetime(1970,1,1)).total_seconds())
        to_d_t = str((self.ToDateTime.dateTime().toPyDateTime() - datetime.datetime(1970,1,1)).total_seconds())

        sql_list = []
        sql_list.append(r"""delete from "%s" """%table_name)
        sql_list.append(r"""where obsid = '%s' """%selected_obsid)
        sql_list.append(r"""AND CAST(strftime('%s', date_time) AS NUMERIC) """)
        sql_list.append(r""" >= '%s' """%fr_d_t)
        sql_list.append(r"""AND CAST(strftime('%s', date_time) AS NUMERIC) """)
        sql_list.append(r""" <= '%s' """%to_d_t)
        sql = ''.join(sql_list)

        really_delete = utils.askuser("YesNo", "Do you want to delete the period " +
                                      str(self.FromDateTime.dateTime().toPyDateTime()) + " to " +
                                      str(self.ToDateTime.dateTime().toPyDateTime()) +
                                      " for obsid " + selected_obsid + " from table " + table_name + "?").result
        if really_delete:
            utils.sql_alter_db(sql)
            self.update_plot()
 def calcselected(self):
     obsids = ru(utils.getselectedobjectnames(self.layer), keep_containers=True)
     if not obsids:
         utils.pop_up_info(ru(QCoreApplication.translate('Calclvl',
                                                         'Adjustment aborted! No obsids selected.')),
                           ru(QCoreApplication.translate('Calclvl', 'Error')))
     else:
         self.calc(obsids)
    def settings_strings_dialogs(self):

        msg = ru(QCoreApplication.translate('ExportToFieldLogger', 'Edit the settings string for input fields browser and restart export fieldlogger dialog\nto load the change.'))
        browser_updated = self.ask_and_update_settings([self.parameter_browser], self.stored_settingskey_parameterbrowser, msg)
        msg = ru(QCoreApplication.translate('ExportToFieldLogger', 'Edit the settings string for input fields groups and restart export fieldlogger dialog\nto load the change.'))
        groups_updated = self.ask_and_update_settings(self.parameter_groups, self.stored_settingskey, msg)
        if browser_updated or groups_updated:
            utils.pop_up_info(ru(QCoreApplication.translate('ExportToFieldLogger', 'Settings updated. Restart Export to Fieldlogger dialog\nor press "Save settings" to undo.')))
    def calibrate_from_plot_selection(self):
        """ Calibrates by selecting a line node and a y-position on the plot

            The user have to click on the button three times and follow instructions.
        
            The process:
            1. Selecting a line node.
            2. Selecting a selecting a y-position from the plot.
            3. Extracting the head from head_ts with the same date as the line node.
            4. Calculating y-position - head (or level_masl) and setting self.LoggerPos.
            5. Run calibration.
        """            
        #Run init to make sure self.meas_ts and self.head_ts is updated for the current obsid.           
        self.load_obsid_and_init()
        self.deactivate_pan_zoom()
        self.canvas.setFocusPolicy(Qt.ClickFocus)
        self.canvas.setFocus()

        if self.log_pos is None:
            self.calib_help.setText("Select a logger node.")
            self.cid.append(self.canvas.mpl_connect('pick_event', self.set_log_pos_from_node_date_click))  
        
        if self.log_pos is not None and self.y_pos is None:
            self.calib_help.setText("Select a y position to move to.")
            self.cid.append(self.canvas.mpl_connect('button_press_event', self.set_y_pos_from_y_click))
            
        if self.log_pos is not None and self.y_pos is not None:
            PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor)

            if self.loggerpos_masl_or_offset_state == 1:
                logger_ts = self.head_ts
            else:
                logger_ts = self.level_masl_ts
            
            y_pos = self.y_pos
            log_pos = self.log_pos
            self.y_pos = None
            self.log_pos = None
            log_pos_date = datestring_to_date(log_pos).replace(tzinfo=None)
            logger_value = None

            #Get the value for the selected node
            for idx, date_value_tuple in enumerate(logger_ts):
                raw_date, logger_value = date_value_tuple
                date = datestring_to_date(raw_date).replace(tzinfo=None)
                if date == log_pos_date:
                    break

            if logger_value is None:
                utils.pop_up_info("No connection between head_ts dates and logger date could be made!\nTry again or choose a new logger line node!")   
            else:
                self.LoggerPos.setText(str(float(y_pos) - float(logger_value)))

                PyQt4.QtGui.QApplication.restoreOverrideCursor()
                self.calibrateandplot()

            self.calib_help.setText("")
 def calcall(self):
     obsids = db_utils.sql_load_fr_db("""SELECT DISTINCT obsid FROM w_levels""")[1]
     if obsids:
         obsids = [x[0] for x in obsids]
         self.calc(obsids)
     else:
         utils.pop_up_info(ru(QCoreApplication.translate('Calclvl',
                                                         'Adjustment aborted! No obsids in w_levels.')),
                           ru(QCoreApplication.translate('Calclvl', 'Error')))
Esempio n. 16
0
 def file_data_loaded_popup(self):
     if self.file_data is not None:
         for button in (self.select_file_button,
                        self.import_all_features_button,
                        self.import_selected_features_button):
             button.setEnabled(False)
         utils.pop_up_info(msg=ru(
             QCoreApplication.translate(
                 u'GeneralCsvImportGui',
                 u'File data loaded. Select table to import to.')))
 def write_printlist_to_file(printlist):
     filename = utils.get_save_file_name_no_extension(parent=None, caption=ru(QCoreApplication.translate('ExportToFieldLogger', 'Choose a file name')), directory='', filter='csv (*.csv)')
     if os.path.splitext(filename)[1] != '.csv':
         filename += '.csv'
     try:
         with open(filename, 'w') as f:
             f.write('\n'.join(printlist))
     except IOError as e:
         utils.pop_up_info(ru(QCoreApplication.translate('ExportToFieldLogger', "Writing of file failed!: %s "))%str(e))
     except UnicodeDecodeError as e:
         utils.pop_up_info(ru(QCoreApplication.translate('ExportToFieldLogger', "Error writing %s"))%str(printlist))
Esempio n. 18
0
 def restore_default_settings(self):
     input_field_browser, input_fields_groups = defs.export_fieldlogger_defaults(
     )
     self.update_settings(input_field_browser,
                          self.stored_settingskey_parameterbrowser)
     self.update_settings(input_fields_groups, self.stored_settingskey)
     utils.pop_up_info(
         ru(
             QCoreApplication.translate(
                 u'ExportToFieldLogger',
                 u'Input fields and "Create Input Fields" updated to default.\nRestart Export to Fieldlogger dialog to complete,\nor press "Save settings" to save current input fields settings again.'
             )))
Esempio n. 19
0
 def excecute_sqlfile(self, sqlfilename):
     with open(sqlfilename, 'r') as f:
         f.readline()  # first line is encoding info....
         for line in f:
             if not line:
                 continue
             if line.startswith("#"):
                 continue
             try:
                 self.cur.execute(line)  # use tags to find and replace SRID and versioning info
             except Exception, e:
                 utils.pop_up_info('Failed to create DB! sql failed:\n' + line + '\n\nerror msg:\n' + str(e))
Esempio n. 20
0
    def get_search_radius(self):
        """ Get the period search radius, default to 10 minutes """
        if not self.bestFitSearchRadius.text():
            search_radius = '10 minutes'
            self.bestFitSearchRadius.setText(search_radius)
        else:
            search_radius = self.bestFitSearchRadius.text()

        search_radius_splitted = search_radius.split()
        if len(search_radius_splitted) != 2:
            utils.pop_up_info("Must write time resolution also, ex. 10 minutes")
        return tuple(search_radius_splitted)
    def get_tolerance(self):
        """ Get the period tolerance, default to 10 minutes """
        if not self.bestFitTolerance.text():
            tol = '10 minutes'
            self.bestFitTolerance.setText(tol)
        else:
            tol = self.bestFitTolerance.text()

        tol_splitted = tol.split()
        if len(tol_splitted) != 2:
            utils.pop_up_info("Must write time resolution also, ex. 10 minutes")
        return tuple(tol_splitted)
    def get_search_radius(self):
        """ Get the period search radius, default to 10 minutes """
        if not self.bestFitSearchRadius.text():
            search_radius = '10 minutes'
            self.bestFitSearchRadius.setText(search_radius)
        else:
            search_radius = self.bestFitSearchRadius.text()

        search_radius_splitted = ru(search_radius).split()
        if len(search_radius_splitted) != 2:
            utils.pop_up_info(ru(QCoreApplication.translate('Calibrlogger', "Must write time resolution also, ex. %s"))%'10 minutes')
        return tuple(search_radius_splitted)
Esempio n. 23
0
 def GetData(self, obsid = '', tablename='', debug = 'n'):            # GetData method that returns a table with water quality data
     # Load all data in obs_points table
     sql = r"""select * from """
     sql += tablename
     sql += r""" where obsid = '"""
     sql += obsid   
     sql += r"""'"""
     if tablename == 'stratigraphy':
         sql += r""" order by stratid"""
     if debug == 'y':
         utils.pop_up_info(sql)
     ConnectionOK, data = utils.sql_load_fr_db(sql)
     return ConnectionOK, data
 def __init__(self, observations=[]):#observations is supposed to be a list of unicode strings
     self.observations = observations
     i = 0
     for obs in observations:
             self.observations[i] = obs.encode('utf-8') #turn into a list of python byte strings
             i += 1
     self.sqlpart2 =(str(self.observations).encode('utf-8').replace('[','(')).replace(']',')')#turn list into string and also encode to utf-8 byte string to enable replace
     """check whether there are observations without coordinates"""
     sql = r"""select obsid from obs_points where (east is null or east ='' or  north is null or north = '') and obsid in """ + self.sqlpart2
     ConnectionOK, result = utils.sql_load_fr_db(sql)
     if len(result)==0:
         self.do_it()
     else:
         utils.pop_up_info("Coordinates are missing for\n" + result[0][0] + "\nPositions (geometry) will not be updated.")
Esempio n. 25
0
    def choose_method(self):
        tables_columns = self.tables_columns
        file_header = self.file_header
        import_method_name = self.import_method
        try:
            layer = utils.find_layer(import_method_name)
        except utils.UsageError:
            pass
        else:
            if layer is not None:
                if layer.isEditable():
                    utils.pop_up_info(ru(QCoreApplication.translate('ImportTableChooser', "Layer %s is currently in editing mode.\nPlease exit this mode before proceeding with this operation."))%str(layer.name()), ru(QCoreApplication.translate('GeneralCsvImportGui', "Error")),)
                    self.import_method = ''
                    import_method_name = None

        self.specific_table_info.setText(defs.specific_table_info.get(import_method_name, ''))

        if file_header is None:
            return None


        try:
            self.layout.removeWidget(self.grid.widget)
            self.grid.widget.close()
        except:
            pass

        self.columns = []

        if not import_method_name:
            return None

        self.grid = RowEntryGrid()
        self.layout.addWidget(self.grid.widget)

        self.grid.layout.addWidget(qgis.PyQt.QtWidgets.QLabel(ru(QCoreApplication.translate('ImportTableChooser', 'Column name'))), 0, 0)
        self.grid.layout.addWidget(qgis.PyQt.QtWidgets.QLabel(ru(QCoreApplication.translate('ImportTableChooser', 'File column'))), 0, 1)
        self.grid.layout.addWidget(qgis.PyQt.QtWidgets.QLabel(ru(QCoreApplication.translate('ImportTableChooser', 'Static value'))), 0, 2)
        self.grid.layout.addWidget(qgis.PyQt.QtWidgets.QLabel(ru(QCoreApplication.translate('ImportTableChooser', 'Factor'))), 0, 3)
        self.grid.layout.addWidget(qgis.PyQt.QtWidgets.QLabel(ru(QCoreApplication.translate('ImportTableChooser', 'Ignore not null warning'))), 0, 4)

        for index, tables_columns_info in enumerate(sorted(tables_columns[import_method_name], key=itemgetter(0))):
            column = ColumnEntry(tables_columns_info, file_header, self.numeric_datatypes)
            rownr = self.grid.layout.rowCount()
            for colnr, wid in enumerate(column.column_widgets):
                self.grid.layout.addWidget(wid, rownr, colnr)
            self.columns.append(column)

        self.grid.layout.setColumnStretch(5, 5)
 def showSurvey(self):
     #lyr = self.iface.activeLayer() # THIS IS TSPLOT-method, GETS THE SELECTED LAYER
     lyr = self.layer
     ids = lyr.selectedFeaturesIds()
     if len(ids) == 0:
         utils.pop_up_info("No selection", "No features are selected")   
         return
     # initiate the datastore if not yet done   
     self.initStore()   
     PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor)  # Sets the mouse cursor to wait symbol
     try:  # return from store.getData is stored in data only if no object belonging to DataSanityError class is created
         data = self.store.getData(ids, lyr)    # added lyr as an argument!!!
     except DataSanityError, e: # if an object 'e' belonging to DataSanityError is created, then do following
         PyQt4.QtGui.QApplication.restoreOverrideCursor()
         utils.pop_up_info("Data sanity problem, obsid: %s\n%s" % (e.sond_id, e.message))
         return
    def choose_method(self):
        tables_columns = self.tables_columns
        file_header = self.file_header
        import_method_name = self.import_method
        layer = utils.find_layer(import_method_name)
        if layer is not None:
            if layer.isEditable():
                utils.pop_up_info(ru(QCoreApplication.translate('ImportTableChooser', "Layer %s is currently in editing mode.\nPlease exit this mode before proceeding with this operation."))%str(layer.name()), ru(QCoreApplication.translate('GeneralCsvImportGui', "Error")),)
                self.import_method = ''
                import_method_name = None

        self.specific_table_info.setText(defs.specific_table_info.get(import_method_name, ''))

        if file_header is None:
            return None

        #Remove stretch
        self.layout.takeAt(-1)

        try:
            self.layout.removeWidget(self.grid.widget)
            self.grid.widget.close()
        except:
            pass

        self.columns = []

        if not import_method_name:
            self.layout.insertStretch(-1, 4)
            return None

        self.grid = RowEntryGrid()
        self.layout.addWidget(self.grid.widget)

        self.grid.layout.addWidget(qgis.PyQt.QtWidgets.QLabel(ru(QCoreApplication.translate('ImportTableChooser', 'Column name'))), 0, 0)
        self.grid.layout.addWidget(qgis.PyQt.QtWidgets.QLabel(ru(QCoreApplication.translate('ImportTableChooser', 'File column'))), 0, 1)
        self.grid.layout.addWidget(qgis.PyQt.QtWidgets.QLabel(ru(QCoreApplication.translate('ImportTableChooser', 'Static value'))), 0, 2)
        self.grid.layout.addWidget(qgis.PyQt.QtWidgets.QLabel(ru(QCoreApplication.translate('ImportTableChooser', 'Factor'))), 0, 3)

        for index, tables_columns_info in enumerate(sorted(tables_columns[import_method_name], key=itemgetter(0))):
            column = ColumnEntry(tables_columns_info, file_header, self.numeric_datatypes)
            rownr = self.grid.layout.rowCount()
            for colnr, wid in enumerate(column.column_widgets):
                self.grid.layout.addWidget(wid, rownr, colnr)
            self.columns.append(column)

        self.layout.insertStretch(-1, 4)
Esempio n. 28
0
 def GetData(
     self,
     obsid='',
     tablename='',
     debug='n'
 ):  # GetData method that returns a table with water quality data
     # Load all data in obs_points table
     sql = r"""select * from """
     sql += tablename
     sql += r""" where obsid = '"""
     sql += obsid
     sql += r"""'"""
     if tablename == 'stratigraphy':
         sql += r""" order by stratid"""
     if debug == 'y':
         utils.pop_up_info(sql)
     ConnectionOK, data = db_utils.sql_load_fr_db(sql)
     return ConnectionOK, data
Esempio n. 29
0
 def showSurvey(self):
     #lyr = self.iface.activeLayer() # THIS IS TSPLOT-method, GETS THE SELECTED LAYER
     lyr = self.layer
     ids = lyr.selectedFeatureIds()
     if len(ids) == 0:
         utils.pop_up_info(
             ru(QCoreApplication.translate(' Stratigraphy',
                                           "No selection")),
             ru(
                 QCoreApplication.translate(' Stratigraphy',
                                            "No features are selected")))
         return
     # initiate the datastore if not yet done
     self.initStore()
     utils.start_waiting_cursor()  # Sets the mouse cursor to wait symbol
     try:  # return from store.getData is stored in data only if no object belonging to DataSanityError class is created
         self.data = self.store.getData(ids,
                                        lyr)  # added lyr as an argument!!!
     except DataSanityError as e:  # if an object 'e' belonging to DataSanityError is created, then do following
         print("DataSanityError %s" % str(e))
         utils.stop_waiting_cursor()
         utils.pop_up_info(
             ru(
                 QCoreApplication.translate(
                     ' Stratigraphy', "Data sanity problem, obsid: %s\n%s"))
             % (e.sond_id, e.message))
         return
     except Exception as e:  # if an object 'e' belonging to DataSanityError is created, then do following
         print("exception : %s" % str(e))
         utils.stop_waiting_cursor()
         utils.MessagebarAndLog.critical(bar_msg=ru(
             QCoreApplication.translate(
                 ' Stratigraphy',
                 "The stratigraphy plot failed, check Midvatten plugin settings and your data!"
             )))
         return
     utils.stop_waiting_cursor(
     )  # Restores the mouse cursor to normal symbol
     # show widget
     w = SurveyDialog()
     #w.widget.setData2_nosorting(data)  #THIS IS IF DATA IS NOT TO BE SORTED!!
     w.widget.setData(self.data)  #THIS IS ONLY TO SORT DATA!!
     w.show()
     self.w = w  # save reference so it doesn't get deleted immediately        This has to be done both here and also in midvatten instance
    def load_obsid_and_init(self):
        """ Checks the current obsid and reloads all ts.
        :return: obsid

        Info: Before, some time series was only reloaded when the obsid was changed, but this caused a problem if the
        data was changed in the background in for example spatialite gui. Now all time series are reloaded always.
        It's rather fast anyway.
        """
        obsid = unicode(self.combobox_obsid.currentText())
        if not obsid:
            utils.pop_up_info("ERROR: no obsid is chosen")

        meas_sql = r"""SELECT date_time, level_masl FROM w_levels WHERE obsid = '""" + obsid + """' ORDER BY date_time"""
        self.meas_ts = self.sql_into_recarray(meas_sql)
        head_sql = r"""SELECT date_time as 'date [datetime]', head_cm / 100 FROM w_levels_logger WHERE obsid = '""" + obsid + """' ORDER BY date_time"""
        self.head_ts = self.sql_into_recarray(head_sql)
        self.obsid = obsid
        level_masl_ts_sql = r"""SELECT date_time as 'date [datetime]', level_masl FROM w_levels_logger WHERE obsid = '""" + self.obsid + """' ORDER BY date_time"""
        self.level_masl_ts = self.sql_into_recarray(level_masl_ts_sql)
        return obsid
    def calc(self, obsids):
        fr_d_t = self.FromDateTime.dateTime().toPyDateTime()
        to_d_t = self.ToDateTime.dateTime().toPyDateTime()
        sql = """SELECT obsid FROM obs_points WHERE obsid IN ({}) AND h_toc IS NULL""".format(', '.join(["'{}'".format(x) for x in obsids]))

        obsid_with_h_toc_null = db_utils.sql_load_fr_db(sql)[1]
        if obsid_with_h_toc_null:
            obsid_with_h_toc_null = [x[0] for x in obsid_with_h_toc_null]
            if self.checkBox_stop_if_null.isChecked():
                any_nulls = [obsid for obsid in obsids if obsid in obsid_with_h_toc_null]
                if any_nulls:
                    utils.pop_up_info(ru(QCoreApplication.translate('Calclvl', 'Adjustment aborted! There seems to be NULL values in your table obs_points, column h_toc.')), ru(QCoreApplication.translate('Calclvl', 'Error')))
                    return None

            else:
                obsids = [obsid for obsid in obsids if obsid not in obsid_with_h_toc_null]

            if not obsids:
                utils.pop_up_info(ru(QCoreApplication.translate('Calclvl',
                                                                'Adjustment aborted! All h_tocs were NULL.')),
                                  ru(QCoreApplication.translate('Calclvl', 'Error')))
                return None

        formatted_obsids = ', '.join(["'{}'".format(x) for x in obsids])
        where_args = {'fr_dt': str(fr_d_t), 'to_dt': str(to_d_t), 'obsids': formatted_obsids}
        where_sql = """meas IS NOT NULL AND date_time >= '{fr_dt}' AND date_time <= '{to_dt}' AND obsid IN ({obsids})""".format(**where_args)
        if not self.checkBox_overwrite_prev.isChecked():
            where_sql += """ AND level_masl IS NULL """

        sql1 = """UPDATE w_levels SET h_toc = (SELECT obs_points.h_toc FROM obs_points WHERE w_levels.obsid = obs_points.obsid) WHERE {}""".format(where_sql)
        self.updated_h_tocs = self.log_msg(where_sql)
        db_utils.sql_alter_db(sql1)

        where_sql += """ AND h_toc IS NOT NULL"""
        sql2 = """UPDATE w_levels SET level_masl = h_toc - meas WHERE h_toc IS NOT NULL AND {}""".format(where_sql)
        self.updated_level_masl = self.log_msg(where_sql)
        db_utils.sql_alter_db(sql2)

        utils.MessagebarAndLog.info(bar_msg=ru(QCoreApplication.translate('Calclvl', 'Calculation done, see log message panel')),
                                    log_msg=ru(QCoreApplication.translate('Calclvl', 'H_toc added and level_masl calculated for\nobsid;min date;max date;calculated number of measurements: \n%s'))%(self.updated_level_masl))
        self.close()
Esempio n. 32
0
 def write_printlist_to_file(printlist):
     filename = PyQt4.QtGui.QFileDialog.getSaveFileName(
         parent=None,
         caption=ru(
             QCoreApplication.translate(u'ExportToFieldLogger',
                                        u'Choose a file name')),
         directory='',
         filter='csv (*.csv)')
     if not filename:
         return
     if os.path.splitext(filename)[1] != u'.csv':
         filename += u'.csv'
     try:
         with open(filename, 'w') as f:
             f.write(u'\n'.join(printlist).encode('utf-8'))
     except IOError, e:
         utils.pop_up_info(
             ru(
                 QCoreApplication.translate(
                     u'ExportToFieldLogger',
                     u"Writing of file failed!: %s ")) % str(e))
Esempio n. 33
0
    def calc_best_fit(self):
        """ Calculates the self.LoggerPos from self.meas_ts and self.head_ts
        
            First matches measurements from self.meas_ts to logger values from
            self.head_ts. This is done by making a mean of all logger values inside
            self.meas_ts date - search_radius and self.meas_ts date + search_radius.
            (this could probably be change to get only the closest logger value
            inside the search_radius instead)
            (search_radius is gotten from self.get_search_radius())
            
            Then calculates the mean of all matches and set to self.LoggerPos.
        """
        obsid = self.load_obsid_and_init()
        self.reset_plot_selects_and_calib_help()
        search_radius = self.get_search_radius()
        if self.loggerpos_masl_or_offset_state == 1:# UPDATE TO RELEVANT TEXT
            logger_ts = self.head_ts
            text_field = self.LoggerPos
            calib_func = self.set_logger_pos
            really_calibrate_question = utils.askuser("YesNo", """This will calibrate all values inside the chosen period\nusing the mean difference between head_cm and w_levels measurements.\n\nSearch radius for matching logger and measurement nodes set to '""" + ' '.join(search_radius) + """'\n\nContinue?""")
        else:# UPDATE TO RELEVANT TEXT
            logger_ts = self.level_masl_ts
            text_field = self.Add2Levelmasl
            calib_func = self.add_to_level_masl
            really_calibrate_question = utils.askuser("YesNo", """This will calibrate all values inside the chosen period\nusing the mean difference between level_masl and w_levels measurements.\n\nSearch radius for matching logger and measurement nodes set to '""" + ' '.join(search_radius) + """'\n\nContinue?""")
        if really_calibrate_question.result == 0: # if the user wants to abort
            return

        PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor)

        coupled_vals = self.match_ts_values(self.meas_ts, logger_ts, search_radius)
        if not coupled_vals:
            utils.pop_up_info("There was no matched measurements or logger values inside the chosen period.\n Try to increase the search radius!")
        else:
            text_field.setText(str(utils.calc_mean_diff(coupled_vals)))
            calib_func()

        PyQt4.QtGui.QApplication.restoreOverrideCursor()
    def calc_best_fit(self):
        """ Calculates the self.LoggerPos from self.meas_ts and self.head_ts

            First matches measurements from self.meas_ts to logger values from
            self.head_ts. This is done by making a mean of all logger values inside
            self.meas_ts date - search_radius and self.meas_ts date + search_radius.
            (this could probably be change to get only the closest logger value
            inside the search_radius instead)
            (search_radius is gotten from self.get_search_radius())

            Then calculates the mean of all matches and set to self.LoggerPos.
        """
        obsid = self.load_obsid_and_init()
        utils.start_waiting_cursor()
        self.reset_plot_selects_and_calib_help()
        search_radius = self.get_search_radius()
        if self.loggerpos_masl_or_offset_state == 1:# UPDATE TO RELEVANT TEXT
            logger_ts = self.head_ts
            text_field = self.LoggerPos
            calib_func = self.set_logger_pos
        else:# UPDATE TO RELEVANT TEXT
            logger_ts = self.level_masl_ts
            text_field = self.Add2Levelmasl
            calib_func = self.add_to_level_masl

        coupled_vals = self.match_ts_values(self.meas_ts, logger_ts, search_radius)
        if not coupled_vals:
            utils.pop_up_info(ru(QCoreApplication.translate('Calibrlogger', "There was no match found between measurements and logger values inside the chosen period.\n Try to increase the search radius!")))
        else:
            calculated_diff = str(utils.calc_mean_diff(coupled_vals))
            if not calculated_diff or calculated_diff.lower() == 'nan':
                utils.pop_up_info(ru(QCoreApplication.translate('Calibrlogger', "There was no matched measurements or logger values inside the chosen period.\n Try to increase the search radius!")))
                utils.MessagebarAndLog.info(log_msg=ru(QCoreApplication.translate('Calibrlogger', "Calculated water level from logger: utils.calc_mean_diff(coupled_vals) didn't return a useable value.")))
            else:
                text_field.setText(calculated_diff)
                calib_func(obsid)

        utils.stop_waiting_cursor()
    def calibrate(self):
        self.calib_help.setText("Calibrating")
        PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor)
        obsid = self.load_obsid_and_init()
        if not obsid=='':        
            sanity1sql = """select count(obsid) from w_levels_logger where obsid = '""" +  obsid[0] + """'"""
            sanity2sql = """select count(obsid) from w_levels_logger where head_cm not null and head_cm !='' and obsid = '""" +  obsid[0] + """'"""
            if utils.sql_load_fr_db(sanity1sql)[1] == utils.sql_load_fr_db(sanity2sql)[1]: # This must only be done if head_cm exists for all data
                fr_d_t = self.FromDateTime.dateTime().toPyDateTime()
                to_d_t = self.ToDateTime.dateTime().toPyDateTime()

                if self.loggerpos_masl_or_offset_state == 1:
                    self.update_level_masl_from_head(obsid, fr_d_t, to_d_t, self.LoggerPos.text())
                else:
                    self.update_level_masl_from_level_masl(obsid, fr_d_t, to_d_t, self.LoggerPos.text())

                self.getlastcalibration()
            else:
                utils.pop_up_info("Calibration aborted!!\nThere must not be empty cells or\nnull values in the 'head_cm' column!")
        else:
            self.INFO.setText("Select the observation point with logger data to be calibrated.")
        self.calib_help.setText("")
        PyQt4.QtGui.QApplication.restoreOverrideCursor()
Esempio n. 36
0
    def __init__(self, obsids=[''], settingsdict={}):

        reportfolder = os.path.join(QDir.tempPath(), 'midvatten_reports')
        if not os.path.exists(reportfolder):
            os.makedirs(reportfolder)
        reportpath = os.path.join(reportfolder, "drill_report.html")
        logopath = os.path.join(os.sep, os.path.dirname(__file__), "..",
                                "templates", "midvatten_logga.png")
        imgpath = os.path.join(os.sep, os.path.dirname(__file__), "..",
                               "templates")

        if len(obsids) == 0:
            utils.pop_up_info(
                ru(
                    QCoreApplication.translate(
                        'Drillreport', "Must select one or more obsids!")))
            return None
        elif len(obsids) == 1:
            merged_question = False
        else:
            #Due to problems regarding speed when opening many tabs, only the merge mode is used.
            #merged_question = utils.Askuser(question='YesNo', msg="Do you want to open all drill reports merged on the same tab?\n"
            #                                    "Else they will be opened separately.\n\n(If answering no, creating drill reports for many obsids take 0.2 seconds per obsid.\nIt might fail if the computer is to slow.\nIf it fails, try to select only one obsid at the time)").result
            merged_question = True

        obsids = sorted(set(obsids))
        if merged_question:
            f, rpt = self.open_file(', '.join(obsids), reportpath)
            for obsid in obsids:
                self.write_obsid(obsid, rpt, imgpath, logopath, f)
            self.close_file(f, reportpath)
        else:
            #opened = False
            for obsid in obsids:
                f, rpt = self.open_file(obsid, reportpath)
                self.write_obsid(obsid, rpt, imgpath, logopath, f)
                url_status = self.close_file(f, reportpath)
 def _getDataStep1(self, featureIds, vlayer):
     """ STEP 1: get data from selected layer"""  # _CHANGE_ Completely revised to TSPLot method
     provider = vlayer.dataProvider()  #_CHANGE_  THIS IS TSPLOT-method, we do not use the db loadeds by ARPAT _init_ surveystore
     obsid_ColNo = provider.fieldNameIndex('obsid') # _CHANGE_  THIS IS TSPLOT-method To find the column named 'obsid'
     if obsid_ColNo == -1:
         obsid_ColNo = provider.fieldNameIndex('OBSID') # backwards compatibility
     h_gs_ColNo = provider.fieldNameIndex('h_gs') # _CHANGE_  THIS IS TSPLOT-method To find the column named 'h_gs'
     h_toc_ColNo = provider.fieldNameIndex('h_toc') # _CHANGE_  THIS IS TSPLOT-method To find the column named 'h_toc'
     if h_gs_ColNo == -1 and h_toc_ColNo == -1:
         h_gs_ColNo = provider.fieldNameIndex('SURF_LVL') # backwards compatibility
     surveys = {}
     strata = {}
     if(vlayer):
         nF = vlayer.selectedFeatureCount()
         if (nF > 0):
             # Load all selected observation points
             ob = vlayer.selectedFeatures()
             obsid_list=[None]*nF # List for obsid
             toplvl_list=[None]*nF # List for top_lvl
             coord_list=[None]*nF # List for coordinates
             i=0
             for k in ob:    # Loop through all selected objects, a plot is added for each one of the observation points (i.e. selected objects)
                 attributes = ob[i]
                 obsid_list[i] = unicode(str(attributes[obsid_ColNo])) # Copy value in column obsid in the attribute list 
                 if attributes[h_gs_ColNo] and utils.isfloat(attributes[h_gs_ColNo]) and  attributes[h_gs_ColNo]>-999:  # Only get h_gs if it exists 
                     toplvl_list[i] = attributes[h_gs_ColNo] # Copy value in column h_gs in the attribute list
                 elif attributes[h_toc_ColNo] and utils.isfloat(attributes[h_toc_ColNo]) and attributes[h_toc_ColNo] >-999:    # else get h_toc if that exists
                     toplvl_list[i] = attributes[h_toc_ColNo] # Copy value in column h_gs in the attribute list
                 else:       # otherwise, if neither h_gs nor h_toc exists - plot as if h_gs is zero
                     toplvl_list[i] = 0
                 coord_list[i]= k.geometry().asPoint()
                 # add to array
                 surveys[obsid_list[i]] = SurveyInfo(obsid_list[i], toplvl_list[i], coord_list[i])
                 i = i+1
     else:
         utils.pop_up_info("getDataStep1 failed ")  # _CHANGE_ for debugging
     return surveys
Esempio n. 38
0
    def __init__(self, parent, midv_settings):
        self.iface = parent

        self.ms = midv_settings
        PyQt4.QtGui.QDialog.__init__(self, parent)
        self.setAttribute(PyQt4.QtCore.Qt.WA_DeleteOnClose)
        self.setupUi(self)  # Required by Qt4 to initialize the UI
        self.setWindowTitle(
            ru(
                QCoreApplication.translate(u'ExportToFieldLogger',
                                           u"Export to Fieldlogger dialog"))
        )  # Set the title for the dialog

        self.widget.setMinimumWidth(180)

        tables_columns = db_utils.tables_columns()

        self.parameter_groups = None

        self.stored_settingskey = 'fieldlogger_export_pgroups'
        self.stored_settingskey_parameterbrowser = 'fieldlogger_export_pbrowser'

        for settingskey in [
                self.stored_settingskey,
                self.stored_settingskey_parameterbrowser
        ]:
            if settingskey not in self.ms.settingsdict:
                utils.MessagebarAndLog.warning(bar_msg=ru(
                    QCoreApplication.translate(
                        u'ExportToFieldLogger',
                        u'%s did not exist in settingsdict')) % settingskey)

        self.parameter_groups = self.create_parameter_groups_using_stored_settings(
            utils.get_stored_settings(self.ms, self.stored_settingskey),
            self.connect)
        if self.parameter_groups is None or not self.parameter_groups:
            self.parameter_groups = [ParameterGroup(self.connect)]

        self.main_vertical_layout.addWidget(
            PyQt4.QtGui.QLabel(
                ru(
                    QCoreApplication.translate(
                        u'ExportToFieldLogger',
                        u'Fieldlogger input fields and locations:'))))
        self.main_vertical_layout.addWidget(get_line())
        self.splitter = SplitterWithHandel(PyQt4.QtCore.Qt.Vertical)
        self.main_vertical_layout.addWidget(self.splitter)

        #This is about adding a messagebar to the fieldlogger window. But for some reason qgis crashes or closes
        #when the timer ends for the regular messagebar
        #self.lbl = MessageBar(self.splitter)
        #qgis.utils.iface.optional_bar = self.lbl

        self.widgets_layouts = self.init_splitters_layouts(self.splitter)

        if self.parameter_groups:
            for export_object in self.parameter_groups:
                self.add_parameter_group_to_gui(self.widgets_layouts,
                                                export_object)

        #Buttons

        #ParameterUnitBrowser
        self.parameter_browser = ParameterBrowser(tables_columns, self.connect,
                                                  self.widget)
        self.parameter_browser_button = PyQt4.QtGui.QPushButton(
            ru(
                QCoreApplication.translate(u'ExportToFieldLogger',
                                           u'Create Input Fields')))
        self.gridLayout_buttons.addWidget(self.parameter_browser_button, 0, 0)
        self.connect(self.parameter_browser_button,
                     PyQt4.QtCore.SIGNAL("clicked()"),
                     lambda: self.parameter_browser.show())

        self.update_parameter_browser_using_stored_settings(
            utils.get_stored_settings(
                self.ms, self.stored_settingskey_parameterbrowser),
            self.parameter_browser)

        self.add_parameter_group = PyQt4.QtGui.QPushButton(
            ru(
                QCoreApplication.translate(u'ExportToFieldLogger',
                                           u'More Fields and Locations')))
        self.add_parameter_group.setToolTip(
            ru(
                QCoreApplication.translate(
                    u'ExportToFieldLogger',
                    u'Creates an additional empty input field group.')))
        self.gridLayout_buttons.addWidget(self.add_parameter_group, 1, 0)
        #Lambda and map is used to run several functions for every button click
        self.connect(
            self.add_parameter_group, PyQt4.QtCore.SIGNAL("clicked()"),
            lambda: map(lambda x: x(), [
                lambda: self.parameter_groups.append(
                    ParameterGroup(self.connect)),
                lambda: self.add_parameter_group_to_gui(
                    self.widgets_layouts, self.parameter_groups[-1])
            ]))

        self.gridLayout_buttons.addWidget(get_line(), 2, 0)

        #Buttons
        self.save_settings_button = PyQt4.QtGui.QPushButton(
            ru(
                QCoreApplication.translate(u'ExportToFieldLogger',
                                           u'Save settings')))
        self.save_settings_button.setToolTip(
            ru(
                QCoreApplication.translate(
                    u'ExportToFieldLogger',
                    u'Saves the current input fields settings.')))
        self.gridLayout_buttons.addWidget(self.save_settings_button, 3, 0)
        self.connect(
            self.save_settings_button, PyQt4.QtCore.SIGNAL("clicked()"),
            lambda: map(lambda x: x(), [
                lambda: utils.save_stored_settings(
                    self.ms, self.update_stored_settings(
                        self.parameter_groups), self.stored_settingskey),
                lambda: utils.save_stored_settings(
                    self.ms,
                    self.update_stored_settings([self.parameter_browser]), self
                    .stored_settingskey_parameterbrowser)
            ]))

        self.clear_settings_button = PyQt4.QtGui.QPushButton(
            ru(
                QCoreApplication.translate(u'ExportToFieldLogger',
                                           u'Clear settings')))
        self.clear_settings_button.setToolTip(
            ru(
                QCoreApplication.translate(
                    u'ExportToFieldLogger',
                    u'Clear all input fields settings.')))
        self.gridLayout_buttons.addWidget(self.clear_settings_button, 4, 0)
        self.connect(
            self.clear_settings_button, PyQt4.QtCore.SIGNAL("clicked()"),
            lambda: map(lambda x: x(), [
                lambda: utils.save_stored_settings(self.ms, [
                ], self.stored_settingskey), lambda: utils.pop_up_info(
                    ru(
                        QCoreApplication.translate(
                            u'ExportToFieldLogger',
                            u'Settings cleared. Restart Export to Fieldlogger dialog to complete,\nor press "Save settings" to save current input fields settings again.'
                        )))
            ]))

        self.settings_strings_button = PyQt4.QtGui.QPushButton(
            ru(
                QCoreApplication.translate(u'ExportToFieldLogger',
                                           u'Settings strings')))
        self.settings_strings_button.setToolTip(
            ru(
                QCoreApplication.translate(
                    u'ExportToFieldLogger',
                    u'Access the settings strings ("Create input fields" and input fields) to copy and paste all settings between different qgis projects.\n Usage: Select string and copy to a text editor or directly into Settings strings dialog of another qgis project.'
                )))
        self.gridLayout_buttons.addWidget(self.settings_strings_button, 5, 0)
        self.connect(self.settings_strings_button,
                     PyQt4.QtCore.SIGNAL("clicked()"),
                     self.settings_strings_dialogs)

        self.default_settings_button = PyQt4.QtGui.QPushButton(
            ru(
                QCoreApplication.translate(u'ExportToFieldLogger',
                                           u'Default settings')))
        self.default_settings_button.setToolTip(
            ru(
                QCoreApplication.translate(
                    u'ExportToFieldLogger',
                    u'Updates "Create input fields" and input fields to default settings.'
                )))
        self.gridLayout_buttons.addWidget(self.default_settings_button, 6, 0)
        self.connect(self.default_settings_button,
                     PyQt4.QtCore.SIGNAL("clicked()"),
                     self.restore_default_settings)

        self.gridLayout_buttons.addWidget(get_line(), 7, 0)

        self.preview_button = PyQt4.QtGui.QPushButton(
            ru(QCoreApplication.translate(u'ExportToFieldLogger', u'Preview')))
        self.preview_button.setToolTip(
            ru(
                QCoreApplication.translate(
                    u'ExportToFieldLogger',
                    u'View a preview of the Fieldlogger location file as pop-up info.'
                )))
        self.gridLayout_buttons.addWidget(self.preview_button, 8, 0)
        # Lambda and map is used to run several functions for every button click
        self.connect(self.preview_button, PyQt4.QtCore.SIGNAL("clicked()"),
                     self.preview)

        self.export_button = PyQt4.QtGui.QPushButton(
            ru(QCoreApplication.translate(u'ExportToFieldLogger', u'Export')))
        self.export_button.setToolTip(
            ru(
                QCoreApplication.translate(
                    u'ExportToFieldLogger',
                    u'Exports the current combination of locations and input fields to a Fieldlogger location file.'
                )))
        self.gridLayout_buttons.addWidget(self.export_button, 9, 0)
        # Lambda and map is used to run several functions for every button click
        self.connect(self.export_button, PyQt4.QtCore.SIGNAL("clicked()"),
                     self.export)

        self.gridLayout_buttons.setRowStretch(10, 1)

        self.show()
Esempio n. 39
0
    def _getDataStep1(self, featureIds, vlayer):
        """ STEP 1: get data from selected layer"""  # _CHANGE_ Completely revised to TSPLot method
        provider = vlayer.dataProvider(
        )  #_CHANGE_  THIS IS TSPLOT-method, we do not use the db loadeds by ARPAT _init_ surveystore
        obsid_ColNo = provider.fieldNameIndex(
            'obsid'
        )  # _CHANGE_  THIS IS TSPLOT-method To find the column named 'obsid'
        if obsid_ColNo == -1:
            obsid_ColNo = provider.fieldNameIndex(
                'OBSID')  # backwards compatibility
        h_gs_ColNo = provider.fieldNameIndex(
            'h_gs'
        )  # _CHANGE_  THIS IS TSPLOT-method To find the column named 'h_gs'
        h_toc_ColNo = provider.fieldNameIndex(
            'h_toc'
        )  # _CHANGE_  THIS IS TSPLOT-method To find the column named 'h_toc'
        if h_gs_ColNo == -1 and h_toc_ColNo == -1:
            h_gs_ColNo = provider.fieldNameIndex(
                'SURF_LVL')  # backwards compatibility
        surveys = {}
        strata = {}
        if (vlayer):
            nF = vlayer.selectedFeatureCount()
            if (nF > 0):
                # Load all selected observation points
                ob = vlayer.selectedFeatures()
                obsid_list = [None] * nF  # List for obsid
                toplvl_list = [None] * nF  # List for top_lvl
                coord_list = [None] * nF  # List for coordinates
                for i, k in enumerate(
                        ob
                ):  # Loop through all selected objects, a plot is added for each one of the observation points (i.e. selected objects)
                    attributes = ob[i]
                    obsid = ru(attributes[obsid_ColNo])
                    obsid_list[
                        i] = obsid  # Copy value in column obsid in the attribute list
                    h_gs = ru(attributes[h_gs_ColNo])

                    level_val = None

                    error_msg = False

                    if h_gs:
                        try:
                            level_val = float(h_gs)
                        except ValueError:
                            error_msg = ru(
                                QCoreApplication.translate(
                                    u'Stratigraphy',
                                    u'Converting to float failed.'))
                        except Exception as e:
                            error_msg = e

                    if level_val is None:
                        h_toc = ru(attributes[h_toc_ColNo])
                        try:
                            level_val = float(h_toc)
                        except:
                            using = u'-1'
                            level_val = -1
                        else:
                            using = u'h_toc'

                        utils.MessagebarAndLog.warning(bar_msg=ru(
                            QCoreApplication.translate(
                                u'Stratigraphy',
                                u"Obsid %s: using h_gs '%s' failed, using '%s' instead."
                            )) % (obsid, h_gs, using),
                                                       log_msg=ru(
                                                           QCoreApplication.
                                                           translate(
                                                               u'Stratigraphy',
                                                               u'%s')) %
                                                       error_msg,
                                                       duration=90)

                        if self.warning_popup:
                            utils.pop_up_info(
                                ru(
                                    QCoreApplication.translate(
                                        u'Stratigraphy',
                                        u'Warning, h_gs is missing. See messagebar.'
                                    )))
                            self.warning_popup = False

                    toplvl_list[i] = level_val

                    coord_list[i] = k.geometry().asPoint()
                    # add to array
                    surveys[obsid_list[i]] = SurveyInfo(
                        obsid_list[i], toplvl_list[i], coord_list[i])
        else:
            utils.pop_up_info(
                ru(
                    QCoreApplication.translate(
                        u'Stratigraphy',
                        u"getDataStep1 failed")))  # _CHANGE_ for debugging

        return surveys
    def create_new_db(self, verno, user_select_CRS='y', EPSG_code='4326'):#CreateNewDB(self, verno):
        """Open a new DataBase (create an empty one if file doesn't exists) and set as default DB"""
        if user_select_CRS=='y':
            EPSGID=str(self.ask_for_CRS()[0])
        else:
            EPSGID=EPSG_code
        PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor)
        if EPSGID=='0' or not EPSGID:
            utils.pop_up_info("Cancelling...")
        else: # If a CRS is selectd, go on and create the database
            #path and name of new db
            self.dbpath = PyQt4.QtGui.QFileDialog.getSaveFileName(None, "New DB","midv_obsdb.sqlite","Spatialite (*.sqlite)")
            if not self.dbpath:
                PyQt4.QtGui.QApplication.restoreOverrideCursor()
                return ''
            #create Spatialite database
            else:
                try:
                    # creating/connecting the test_db
                    self.conn = sqlite.connect(self.dbpath) 
                    # creating a Cursor
                    self.cur = self.conn.cursor()
                    self.cur.execute("PRAGMA foreign_keys = ON")    #Foreign key constraints are disabled by default (for backwards compatibility), so must be enabled separately for each database connection separately.
                except:
                    utils.pop_up_info("Impossible to connect to selected DataBase")
                    return ''
                    PyQt4.QtGui.QApplication.restoreOverrideCursor()
                #First, find spatialite version
                versionstext = self.cur.execute('select spatialite_version()').fetchall()
                #print versionstext#debug
                # load sql syntax to initialise spatial metadata, automatically create GEOMETRY_COLUMNS and SPATIAL_REF_SYS
                # then the syntax defines a Midvatten project db according to the loaded .sql-file
                if int(versionstext[0][0][0]) > 3: # which file to use depends on spatialite version installed
                    SQLFile = os.path.join(os.sep,os.path.dirname(__file__),"..","definitions","create_db_splite4.sql")
                else:
                    SQLFile = os.path.join(os.sep,os.path.dirname(__file__),"..","definitions","create_db.sql") 
                qgisverno = QGis.QGIS_VERSION#We want to store info about which qgis-version that created the db
                f = open(SQLFile, 'r')
                linecounter = 1
                for line in f:
                    if linecounter > 1:    # first line is encoding info....
                        self.rs = self.cur.execute(line.replace('CHANGETORELEVANTEPSGID',str(EPSGID)).replace('CHANGETOPLUGINVERSION',str(verno)).replace('CHANGETOQGISVERSION',str(qgisverno)).replace('CHANGETOSPLITEVERSION',str(versionstext[0][0]))) # use tags to find and replace SRID and versioning info
                    linecounter += 1

                self.cur.execute("PRAGMA foreign_keys = OFF")
                #FINISHED WORKING WITH THE DATABASE, CLOSE CONNECTIONS
                self.rs.close()
                self.conn.close()
                #create SpatiaLite Connection in QGIS QSettings
                settings=PyQt4.QtCore.QSettings()
                settings.beginGroup('/SpatiaLite/connections')
                #settings.setValue(u'%s/sqlitepath'%os.path.basename(str(self.dbpath)),'%s'%self.dbpath)
                settings.setValue(u'%s/sqlitepath'%os.path.basename(self.dbpath),'%s'%self.dbpath)
                settings.endGroup()

                """
                #The intention is to keep layer styles in the database by using the class AddLayerStyles but due to limitations in how layer styles are stored in the database, I will put this class on hold for a while. 

                #Finally add the layer styles info into the data base
                AddLayerStyles(self.dbpath)
                """
        PyQt4.QtGui.QApplication.restoreOverrideCursor()
Esempio n. 41
0
    def showtheplot(
        self, layer
    ):  # PlotTS method that, at the moment, performs all the real work
        provider = layer.dataProvider()  #Something with OGR
        kolumnindex = provider.fieldNameIndex(
            'obsid')  # To find the column named 'obsid'
        if kolumnindex == -1:
            kolumnindex = provider.fieldNameIndex(
                'OBSID')  # backwards compatibility
        if (layer):
            nF = layer.selectedFeatureCount()
            if (nF > 0):
                # Load all selected observation points
                ob = layer.getSelectedFeatures()

                # Create a plot window with one single subplot
                fig = plt.figure(
                )  # causes conflict with plugins "statist" and "chartmaker"
                ax = fig.add_subplot(111)

                p = [None] * nF  # List for plot objects
                plabel = [None] * nF  # List for label strings

                for i, k in enumerate(
                        ob
                ):  # Loop through all selected objects, a plot is added for each one of the observation points (i.e. selected objects)
                    attributes = k.attributes()
                    obsid = ru(attributes[kolumnindex])
                    # Load all observations (full time series) for the object [i] (i.e. selected observation point no i)
                    sql = r"""SELECT date_time, """
                    sql += str(self.settingsdict['tscolumn'])  #MacOSX fix1
                    sql += """ FROM """
                    sql += str(self.settingsdict['tstable'])  #MacOSX fix1
                    sql += r""" WHERE obsid = '"""
                    sql += obsid
                    sql += """' ORDER BY date_time """
                    connection_ok, recs = db_utils.sql_load_fr_db(sql)
                    """Transform data to a numpy.recarray"""
                    My_format = [
                        ('date_time', datetime.datetime), ('values', float)
                    ]  #Define format with help from function datetime
                    table = np.array(recs, dtype=My_format)  #NDARRAY
                    table2 = table.view(
                        np.recarray
                    )  # RECARRAY   Makes the two columns inte callable objects, i.e. write table2.values
                    """ Get help from function datestr2num to get date and time into float"""
                    myTimestring = []  #LIST
                    for j, row in enumerate(table2):
                        myTimestring.append(table2.date_time[j])
                    numtime = datestr2num(
                        myTimestring
                    )  #conv list of strings to numpy.ndarray of floats
                    if self.settingsdict[
                            'tsdotmarkers'] == 2:  # If the checkbox is checked - markers will be plotted #MacOSX fix1
                        if self.settingsdict[
                                'tsstepplot'] == 2:  # If the checkbox is checked - draw a step plot #MacOSX fix1
                            p[i], = ax.plot_date(numtime,
                                                 table2.values,
                                                 marker='o',
                                                 linestyle='-',
                                                 drawstyle='steps-pre',
                                                 label=obsid)  # PLOT!!
                        else:
                            p[i], = ax.plot_date(numtime,
                                                 table2.values,
                                                 'o-',
                                                 label=obsid)
                    else:  # NO markers wil be plotted, , just a line
                        if self.settingsdict[
                                'tsstepplot'] == 2:  # If the checkbox is checked - draw a step plot #MacOSX fix1
                            p[i], = ax.plot_date(numtime,
                                                 table2.values,
                                                 marker='None',
                                                 linestyle='-',
                                                 drawstyle='steps-pre',
                                                 label=obsid)  # PLOT!!
                        else:
                            p[i], = ax.plot_date(numtime,
                                                 table2.values,
                                                 '-',
                                                 label=obsid)
                    plabel[i] = obsid  # Label for the plot
                """ Finish plot """
                ax.grid(True)
                ax.yaxis.set_major_formatter(
                    tick.ScalarFormatter(useOffset=False, useMathText=False))
                fig.autofmt_xdate()
                ax.set_ylabel(self.settingsdict['tscolumn'])  #MacOSX fix1
                ax.set_title(self.settingsdict['tstable'])  #MacOSX fix1
                leg = fig.legend(p, plabel,
                                 loc=0)  #leg = fig.legend(p, plabel, 'right')
                try:
                    leg.set_draggable(state=True)
                except AttributeError:
                    # For older version of matplotlib
                    leg.draggable(state=True)
                frame = leg.get_frame(
                )  # the matplotlib.patches.Rectangle instance surrounding the legend
                frame.set_facecolor(
                    '0.80')  # set the frame face color to light gray
                frame.set_fill(False)  # set the frame face color transparent

                for t in leg.get_texts():
                    t.set_fontsize(10)  # the legend text fontsize
                for label in ax.xaxis.get_ticklabels():
                    label.set_fontsize(10)
                for label in ax.yaxis.get_ticklabels():
                    label.set_fontsize(10)
                #plt.ion()#force interactivity to prevent the plot window from blocking the qgis app

                fig.show()
                #plt.close(fig)
                #plt.draw()
            else:
                utils.pop_up_info(
                    ru(
                        QCoreApplication.translate(
                            'TimeSeriesPlot',
                            "Please select at least one point with time series data"
                        )))
        else:
            utils.pop_up_info(
                ru(
                    QCoreApplication.translate(
                        'TimeSeriesPlot',
                        "Please select a layer with time series observation points"
                    )))
    def __init__(self, obsids, settingsdict, general_metadata, geo_metadata,
                 strat_columns, header_in_table, skip_empty, include_comments,
                 general_metadata_header, geo_metadata_header,
                 strat_columns_header, comment_header,
                 empty_row_between_obsids, topleft_topright_colwidths,
                 general_colwidth, geo_colwidth, decimal_separator):

        reportfolder = os.path.join(QDir.tempPath(), 'midvatten_reports')
        if not os.path.exists(reportfolder):
            os.makedirs(reportfolder)
        reportpath = os.path.join(reportfolder, "drill_report.html")
        logopath = os.path.join(os.sep, os.path.dirname(__file__), "..",
                                "templates", "midvatten_logga.png")
        imgpath = os.path.join(os.sep, os.path.dirname(__file__), "..",
                               "templates")

        if len(obsids) == 0:
            utils.pop_up_info(
                ru(
                    QCoreApplication.translate(
                        'Drillreport', "Must select one or more obsids!")))
            return None

        obsids = sorted(set(obsids))

        obs_points_translations = {
            'obsid':
            ru(QCoreApplication.translate('Drillreport2', 'obsid')),
            'name':
            ru(QCoreApplication.translate('Drillreport2', 'name')),
            'place':
            ru(QCoreApplication.translate('Drillreport2', 'place')),
            'type':
            ru(QCoreApplication.translate('Drillreport2', 'type')),
            'length':
            ru(QCoreApplication.translate('Drillreport2', 'length')),
            'drillstop':
            ru(QCoreApplication.translate('Drillreport2', 'drillstop')),
            'diam':
            ru(QCoreApplication.translate('Drillreport2', 'diam')),
            'material':
            ru(QCoreApplication.translate('Drillreport2', 'material')),
            'screen':
            ru(QCoreApplication.translate('Drillreport2', 'screen')),
            'capacity':
            ru(QCoreApplication.translate('Drillreport2', 'capacity')),
            'drilldate':
            ru(QCoreApplication.translate('Drillreport2', 'drilldate')),
            'wmeas_yn':
            ru(QCoreApplication.translate('Drillreport2', 'wmeas_yn')),
            'wlogg_yn':
            ru(QCoreApplication.translate('Drillreport2', 'wlogg_yn')),
            'east':
            ru(QCoreApplication.translate('Drillreport2', 'east')),
            'north':
            ru(QCoreApplication.translate('Drillreport2', 'north')),
            'ne_accur':
            ru(QCoreApplication.translate('Drillreport2', 'ne_accur')),
            'ne_source':
            ru(QCoreApplication.translate('Drillreport2', 'ne_source')),
            'h_toc':
            ru(QCoreApplication.translate('Drillreport2', 'h_toc')),
            'h_tocags':
            ru(QCoreApplication.translate('Drillreport2', 'h_tocags')),
            'h_gs':
            ru(QCoreApplication.translate('Drillreport2', 'h_gs')),
            'h_accur':
            ru(QCoreApplication.translate('Drillreport2', 'h_accur')),
            'h_syst':
            ru(QCoreApplication.translate('Drillreport2', 'h_syst')),
            'h_source':
            ru(QCoreApplication.translate('Drillreport2', 'h_source')),
            'source':
            ru(QCoreApplication.translate('Drillreport2', 'source')),
            'com_onerow':
            ru(QCoreApplication.translate('Drillreport2', 'com_onerow')),
            'com_html':
            ru(QCoreApplication.translate('Drillreport2', 'com_html'))
        }
        """
        thelist = [ "obsid", "stratid", "depthtop", "depthbot", "geology", "geoshort", "capacity", "development", "comment"]
        >>> y = '\n'.join(["'%s'"%x + ': ' + "ru(QCoreApplication.translate('Drillreport2', '%s')),"%x for x in thelist])
        >>> print(y)
        """

        dbconnection = db_utils.DbConnectionManager()

        obs_points_cols = [
            "obsid", "name", "place", "type", "length", "drillstop", "diam",
            "material", "screen", "capacity", "drilldate", "wmeas_yn",
            "wlogg_yn", "east", "north", "ne_accur", "ne_source", "h_toc",
            "h_tocags", "h_gs", "h_accur", "h_syst", "h_source", "source",
            "com_onerow", "com_html"
        ]
        all_obs_points_data = ru(db_utils.get_sql_result_as_dict(
            'SELECT %s FROM obs_points WHERE obsid IN (%s) ORDER BY obsid' %
            (', '.join(obs_points_cols), ', '.join(
                ["'{}'".format(x) for x in obsids])),
            dbconnection=dbconnection)[1],
                                 keep_containers=True)

        if strat_columns:
            strat_sql_columns_list = [x.split(';')[0] for x in strat_columns]
            if 'depth' in strat_sql_columns_list:
                strat_sql_columns_list.extend(['depthtop', 'depthbot'])
                strat_sql_columns_list.remove('depth')
                strat_sql_columns_list = [
                    x for x in strat_sql_columns_list if x not in ('obsid')
                ]

            all_stratigrapy_data = ru(db_utils.get_sql_result_as_dict(
                'SELECT obsid, %s FROM stratigraphy WHERE obsid IN (%s) ORDER BY obsid, stratid'
                % (', '.join(strat_sql_columns_list), ', '.join(
                    ["'{}'".format(x) for x in obsids])),
                dbconnection=dbconnection)[1],
                                      keep_containers=True)
        else:
            all_stratigrapy_data = {}
            strat_sql_columns_list = []

        crs = ru(
            db_utils.sql_load_fr_db(
                """SELECT srid FROM geometry_columns where f_table_name = 'obs_points'""",
                dbconnection=dbconnection)[1][0][0])
        crsname = ru(db_utils.get_srid_name(crs, dbconnection=dbconnection))

        dbconnection.closedb()

        f, rpt = self.open_file(', '.join(obsids), reportpath)
        rpt += r"""<html>"""
        for obsid in obsids:
            obs_points_data = all_obs_points_data[obsid][0]
            general_data_no_rounding = [
                x.split(';')[0] for x in general_metadata
            ]
            general_rounding = [
                x.split(';')[1] if len(x.split(';')) == 2 else None
                for x in general_metadata
            ]
            general_data = [
                (obs_points_translations.get(header, header),
                 obs_points_data[obs_points_cols.index(header) - 1])
                for header in general_data_no_rounding
            ]
            if geo_metadata:
                geo_metadata_no_rounding = [
                    x.split(';')[0] for x in geo_metadata
                ]
                geo_rounding = [
                    x.split(';')[1] if len(x.split(';')) == 2 else None
                    for x in geo_metadata
                ]
                geo_data = [
                    (obs_points_translations.get(header, header),
                     obs_points_data[obs_points_cols.index(header) - 1])
                    for header in geo_metadata_no_rounding
                ]
                if 'east' in geo_metadata_no_rounding or 'north' in geo_metadata_no_rounding:
                    geo_data.append(
                        (ru(
                            QCoreApplication.translate('Drillreport2',
                                                       'XY Reference system')),
                         '%s' % ('%s, ' % crsname if crsname else '') +
                         'EPSG:' + crs))
            else:
                geo_data = []
                geo_rounding = []

            strat_data = all_stratigrapy_data.get(obsid, None)

            if include_comments:
                comment_data = [
                    obs_points_data[obs_points_cols.index(header) - 1]
                    for header in ('com_onerow', 'com_html') if all([
                        obs_points_data[obs_points_cols.index(header) - 1]
                        is not None, obs_points_data[
                            obs_points_cols.index(header) -
                            1].replace('NULL', ''), obs_points_data[
                                obs_points_cols.index(header) -
                                1].strip(), 'text-indent:0px;"><br /></p>'
                        not in obs_points_data[obs_points_cols.index(header) -
                                               1], 'text-indent:0px;"></p>'
                        not in obs_points_data[obs_points_cols.index(header) -
                                               1], 'text-indent:0px;">NULL</p>'
                        not in obs_points_data[obs_points_cols.index(header) -
                                               1].strip()
                    ])
                ]
            else:
                comment_data = []

            rpt += self.write_obsid(
                obsid,
                general_data,
                geo_data,
                strat_data,
                comment_data,
                strat_columns,
                header_in_table=header_in_table,
                skip_empty=skip_empty,
                general_metadata_header=general_metadata_header,
                geo_metadata_header=geo_metadata_header,
                strat_columns_header=strat_columns_header,
                comment_header=comment_header,
                general_rounding=general_rounding,
                geo_rounding=geo_rounding,
                strat_sql_columns_list=strat_sql_columns_list,
                topleft_topright_colwidths=topleft_topright_colwidths,
                general_colwidth=general_colwidth,
                geo_colwidth=geo_colwidth,
                decimal_separator=decimal_separator)
            rpt += r"""<p>    </p>"""
            if empty_row_between_obsids:
                rpt += r"""<p>empty_row_between_obsids</p>"""

        rpt += r"""</html>"""
        f.write(rpt)
        self.close_file(f, reportpath)
Esempio n. 43
0
    def create_new_spatialite_db(self, verno, user_select_CRS='y', EPSG_code='4326', delete_srids=True):  #CreateNewDB(self, verno):
        """Open a new DataBase (create an empty one if file doesn't exists) and set as default DB"""

        utils.stop_waiting_cursor()
        set_locale = self.ask_for_locale()
        utils.start_waiting_cursor()

        if user_select_CRS=='y':
            utils.stop_waiting_cursor()
            EPSGID=str(self.ask_for_CRS(set_locale)[0])
            utils.start_waiting_cursor()
        else:
            EPSGID=EPSG_code

        if EPSGID=='0' or not EPSGID:
            raise utils.UserInterruptError()
        # If a CRS is selectd, go on and create the database

        #path and name of new db
        utils.stop_waiting_cursor()
        dbpath = ru(utils.get_save_file_name_no_extension(parent=None, caption="New DB",
                                                                    directory="midv_obsdb.sqlite",
                                                                    filter="Spatialite (*.sqlite)"))

        utils.start_waiting_cursor()

        if os.path.exists(dbpath):
            utils.MessagebarAndLog.critical(
                bar_msg=ru(QCoreApplication.translate('NewDb', 'A database with the chosen name already existed. Cancelling...')))
            utils.stop_waiting_cursor()
            return ''

        #Create the database
        conn = db_utils.connect_with_spatialite_connect(dbpath)
        conn.close()

        self.db_settings = ru(utils.anything_to_string_representation({'spatialite': {'dbpath': dbpath}}))

        #dbconnection = db_utils.DbConnectionManager(self.db_settings)
        try:
            # creating/connecting the test_db
            dbconnection = db_utils.DbConnectionManager(self.db_settings)
            dbconnection.execute("PRAGMA foreign_keys = ON")    #Foreign key constraints are disabled by default (for backwards compatibility), so must be enabled separately for each database dbconnection separately.
        except Exception as e:
            utils.MessagebarAndLog.critical(bar_msg=ru(QCoreApplication.translate('NewDb', "Impossible to connect to selected DataBase, see log message panel")), log_msg=ru(QCoreApplication.translate('NewDb', 'Msg:\n') + str(e)))
            #utils.pop_up_info("Impossible to connect to selected DataBase")
            utils.stop_waiting_cursor()
            return ''
        d =dbconnection.connector
        #First, find spatialite version
        versionstext = dbconnection.execute_and_fetchall('select spatialite_version()')[0][0]
        # load sql syntax to initialise spatial metadata, automatically create GEOMETRY_COLUMNS and SPATIAL_REF_SYS
        # then the syntax defines a Midvatten project db according to the loaded .sql-file
        if not int(versionstext[0][0]) > 3: # which file to use depends on spatialite version installed
            utils.pop_up_info(ru(QCoreApplication.translate('NewDb', "Midvatten plugin needs spatialite4.\nDatabase can not be created")))
            utils.stop_waiting_cursor()
            return ''

        filenamestring = "create_db.sql"

        SQLFile = os.path.join(os.sep,os.path.dirname(__file__),"..","definitions",filenamestring)
        qgisverno = Qgis.QGIS_VERSION#We want to store info about which qgis-version that created the db
        replace_word_replace_with = [('CHANGETORELEVANTEPSGID', ru(EPSGID)),
                                    ('CHANGETOPLUGINVERSION', ru(verno)),
                                    ('CHANGETOQGISVERSION', ru(qgisverno)),
                                    ('CHANGETODBANDVERSION', 'SpatiaLite version %s'%ru(versionstext)),
                                    ('CHANGETOLOCALE', ru(set_locale)),
                                    (('SPATIALITE ', ''))]

        with open(SQLFile, 'r') as f:
            f.readline()  # first line is encoding info....
            lines = [ru(line) for line in f]
        sql_lines = ['{};'.format(l) for l in ' '.join(lines).split(';') if l]
        for line in sql_lines:
            if all([line, not line.startswith("#"), 'POSTGIS' not in line]):
                sql = self.replace_words(line, replace_word_replace_with)
                try:
                    dbconnection.execute(sql)
                except:
                    try:
                        print(str(sql))
                    except:
                        pass
                    raise

        if delete_srids:
            db_utils.delete_srids(dbconnection, EPSGID)


        self.insert_datadomains(set_locale, dbconnection)

        execute_sqlfile(get_full_filename("insert_obs_points_triggers.sql"), dbconnection)

        execute_sqlfile(get_full_filename('qgis3_obsp_fix.sql'), dbconnection)

        self.add_metadata_to_about_db(dbconnection)

        #FINISHED WORKING WITH THE DATABASE, CLOSE CONNECTIONS

        dbconnection.commit()
        dbconnection.vacuum()
        dbconnection.commit_and_closedb()

        #create SpatiaLite Connection in QGIS QSettings
        settings=qgis.PyQt.QtCore.QSettings()
        settings.beginGroup('/SpatiaLite/dbconnections')
        settings.setValue('%s/sqlitepath'%os.path.basename(dbpath),'%s'%dbpath)
        settings.endGroup()

        """
        #The intention is to keep layer styles in the database by using the class AddLayerStyles but due to limitations in how layer styles are stored in the database, I will put this class on hold for a while.

        #Finally add the layer styles info into the data base
        AddLayerStyles(dbpath)
        """

        utils.stop_waiting_cursor()
Esempio n. 44
0
    def parse(self, filenames):
        """ Reads the interlab
        :param filenames:
        :return: A dict like {<lablittera>: {u'metadata': {u'metadataheader': value, ...}, <par1_name>: {u'dataheader': value, ...}}}
        """
        all_lab_results = {}

        for filename in filenames:
            file_settings = self.parse_filesettings(filename)
            file_error, version, encoding, decimalsign, quotechar = file_settings
            if file_error:
                utils.pop_up_info(
                    ru(
                        QCoreApplication.translate(
                            u'Interlab4Import',
                            u"Warning: The file information %s could not be read. Skipping file"
                        )) % filename)
                continue

            with open(filename, 'rb') as f:
                if quotechar:
                    unicode_reader = utils.UnicodeReader(
                        f,
                        encoding=encoding,
                        quotechar=str(quotechar),
                        delimiter=';')
                else:
                    unicode_reader = utils.UnicodeReader(f,
                                                         encoding=encoding,
                                                         delimiter=';')

                lab_results = {}
                file_error = False
                read_metadata_header = False
                parse_metadata_values = False
                read_data_header = False
                parse_data_values = False

                metadata_header = None
                data_header = None

                for cols in unicode_reader:
                    if not cols:
                        continue

                    if cols[0].lower().startswith(u'#s**t'):
                        break

                    #cols = ru(cols, keep_containers=True)

                    if cols[0].lower().startswith(u'#provadm'):
                        parse_data_values = False
                        parse_metadata_values = False
                        read_data_header = False
                        read_metadata_header = True
                        data_header = None
                        metadata_header = None
                        continue

                    if cols[0].lower().startswith(u'#provdat'):
                        parse_data_values = False
                        parse_metadata_values = False
                        read_metadata_header = False
                        read_data_header = True
                        continue

                    if read_metadata_header:
                        metadata_header = [x.lower() for x in cols]
                        read_metadata_header = False
                        parse_metadata_values = True
                        continue

                    if parse_metadata_values:
                        metadata = dict([(metadata_header[idx],
                                          value.lstrip(' ').rstrip(' '))
                                         for idx, value in enumerate(cols)
                                         if value.lstrip(' ').rstrip(' ')])
                        lab_results.setdefault(metadata[u'lablittera'],
                                               {})[u'metadata'] = metadata
                        continue

                    if read_data_header:
                        data_header = [x.lower() for x in cols]
                        read_data_header = False
                        parse_data_values = True
                        continue

                    if parse_data_values:
                        data = dict([(data_header[idx],
                                      value.lstrip(' ').rstrip(' '))
                                     for idx, value in enumerate(cols)
                                     if value.lstrip(' ').rstrip(' ')])
                        if u'mätvärdetal' in data:
                            data[u'mätvärdetal'] = data[
                                u'mätvärdetal'].replace(decimalsign, '.')

                        if not u'parameter' in data:
                            utils.pop_up_info(
                                ru(
                                    QCoreApplication.translate(
                                        u'Interlab4Import',
                                        "WARNING: Parsing error. The parameter is missing on row %s"
                                    )) % str(cols))
                            continue

                        if data[u'lablittera'] not in lab_results:
                            utils.pop_up_info(
                                ru(
                                    QCoreApplication.translate(
                                        u'Interlab4Import',
                                        "WARNING: Parsing error. Data for %s read before it's metadata."
                                    )) % data['lablittera'])
                            file_error = True
                            break
                        """
                        Kalium (This part is VERY specific to Midvatten data analyses and probably doesn't affect anyone else)

                        Kalium is (in our very specific case) measured using two different methods. A high and a low resolution method.
                        The lowest value for low resolution method is '<2,5' (in the parameter 'mätvärdetext') and '<1' for the high resolution method.
                        If two kalium is present, we try to extract the high resolution method and store that one in the database.
                        If kalium is between 1 and 2,5, the high resolution method will show 1,5 (for example) while the low resolution will show '<2,5'.
                        If kalium is below 1, they will have values '<2,5' and '<1' in 'mätvärdetext'
                        If both are above 2,5, there is no good way to separate them. In that case, use the last one.
                        """
                        if u'kalium' in data[u'parameter'].lower():
                            current_kalium_name = data[u'parameter'].lower()
                            existing_same_names = [
                                x for x in lab_results[data[u'lablittera']]
                                if x == current_kalium_name
                            ]
                            if not existing_same_names:
                                #kalium has not been parsed yet. Keep the current one.
                                pass
                            else:
                                parameter_chosen = False
                                #Method 1: Use mätosäkerhet to find the high resolution kalium.
                                _previous_resolution = lab_results[data[
                                    u'lablittera']][current_kalium_name].get(
                                        u'mätosäkerhet', u'')
                                previous_resolution = _previous_resolution.replace(
                                    u'±', u'').replace(u'<', u'')
                                _current_resolution = data.get(
                                    u'mätosäkerhet', u'')
                                current_resolution = _current_resolution.replace(
                                    u'±', u'').replace(u'<', u'')
                                if previous_resolution and current_resolution:
                                    try:
                                        previous_resolution = float(
                                            previous_resolution)
                                        current_resolution = float(
                                            current_resolution)
                                    except ValueError:
                                        #mätosäkerhet could not be used. Try the other method
                                        parameter_chosen = False
                                        pass
                                    else:
                                        if previous_resolution > current_resolution:
                                            # The current one is the high resolution one. Keep it to overwrite the other one.
                                            parameter_chosen = True
                                            utils.MessagebarAndLog.info(
                                                log_msg=ru(
                                                    QCoreApplication.translate(
                                                        u'Interlab4Import',
                                                        u'Kalium was found more than once. The one with mätosäkerhet %s was used."'
                                                    )) % _current_resolution)
                                        elif current_resolution > previous_resolution:
                                            # The current one is the low resolution one, skip it.
                                            utils.MessagebarAndLog.info(
                                                log_msg=ru(
                                                    QCoreApplication.translate(
                                                        u'Interlab4Import',
                                                        u'Kalium was found more than once. The one with mätosäkerhet %s was used."'
                                                    )) % _previous_resolution)
                                            parameter_chosen = True
                                            continue
                                        elif current_resolution == previous_resolution:
                                            # This method could not be used to find the high resolution one. Try the other method.
                                            parameter_chosen = False

                                if not parameter_chosen:
                                    current_txt = data.get(
                                        u'mätvärdetext', u'').strip(u' ')
                                    previous_txt = lab_results[
                                        data[u'lablittera']][
                                            current_kalium_name].get(
                                                u'mätvärdetext', u'')
                                    #Method 2: Use < and <2.5 limits to try to find the high resolution one.
                                    if current_txt == u'<1' or previous_txt.strip(
                                            u' ').replace(u',',
                                                          u'.') == u'<2.5':
                                        #The current one is the high resolution one. Keep it to overwrite the other one.
                                        utils.MessagebarAndLog.info(log_msg=ru(
                                            QCoreApplication.translate(
                                                u'Interlab4Import',
                                                u'Kalium was found more than once. The one with mätvärdetext %s was used."'
                                            )) % current_txt)
                                        pass
                                    elif current_txt == u'<2.5' or previous_txt.strip(
                                            u' ') == u'<1':
                                        #The current one is the low resolution one, skip it.
                                        utils.MessagebarAndLog.info(log_msg=ru(
                                            QCoreApplication.translate(
                                                u'Interlab4Import',
                                                u'Kalium was found more than once. The one with mätvärdetext %s was used."'
                                            )) % previous_txt)
                                        continue
                                    else:
                                        utils.MessagebarAndLog.info(log_msg=ru(
                                            QCoreApplication.translate(
                                                u'Interlab4Import',
                                                u'Kalium was found more than once. The high resolution one could not be found. The one with mätvärdetext %s was used."'
                                            )) % current_txt)
                                        #Hope that the current one (the last one) is the high resolution one and let it overwrite the existing one
                                        pass

                        lab_results[data[u'lablittera']][
                            data[u'parameter']] = data

                        continue
                if not file_error:
                    all_lab_results.update(lab_results)

        return all_lab_results
Esempio n. 45
0
    def showtheplot(
        self, layer
    ):  # PlotTS method that, at the moment, performs all the real work
        provider = layer.dataProvider()  #Something with OGR
        kolumnindex = provider.fieldNameIndex(
            'obsid')  # To find the column named 'obsid'
        if kolumnindex == -1:
            kolumnindex = provider.fieldNameIndex(
                'OBSID')  # backwards compatibility
        if (layer):
            nF = layer.selectedFeatureCount()
            if (nF > 0):
                # Load all selected observation points
                ob = layer.getSelectedFeatures()

                # Create a plot window with one single subplot
                fig = plt.figure(
                )  # causes conflict with plugins "statist" and "chartmaker"
                ax = fig.add_subplot(111)

                if len(self.y3col):
                    nY = 3
                elif len(self.y2col):
                    nY = 2
                else:
                    nY = 1
                p = [None] * nF * nY  # List for plot objects
                plabel = [None] * nF * nY  # List for label strings

                j = 0
                for feature in ob:  # Loop through all selected objects, a plot is added for each one of the observation points (i.e. selected objects)
                    attributes = feature.attributes()
                    obsid = attributes[
                        kolumnindex]  # Copy value in column obsid in the attribute list
                    # Load all observations (full time series) for the object [i] (i.e. selected observation point no i)
                    sql = r"""SELECT """
                    sql += str(self.xcol)  #MacOSX fix1
                    sql += r""" as 'x'"""
                    if len(self.y1col):
                        sql += r""", """
                        sql += str(self.y1col)  #MacOSX fix1
                        sql += r""" as 'y1'"""
                    if len(self.y2col):
                        sql += r""", """
                        sql += str(self.y2col)  #MacOSX fix1
                        sql += r""" as 'y2'"""
                    if len(self.y3col):
                        sql += r""", """
                        sql += str(self.y3col)  #MacOSX fix1
                        sql += r""" as 'y3'"""
                    sql += """ FROM """
                    sql += str(self.table)  #MacOSX fix1
                    sql += r""" WHERE obsid = '"""
                    sql += obsid
                    sql += """' ORDER BY """
                    sql += str(self.xcol)  #MacOSX fix1
                    connection_ok, recs = db_utils.sql_load_fr_db(sql)
                    """Transform data to a numpy.recarray"""
                    if len(self.y1col):
                        My_format = [('x', float), ('y1', float)]
                    if len(self.y2col):
                        My_format.append(('y2', float))
                    if len(self.y3col):
                        My_format.append(('y3', float))
                    table = np.array(recs, dtype=My_format)  #NDARRAY
                    table2 = table.view(
                        np.recarray
                    )  # RECARRAY   Makes the two columns inte callable objects, i.e. write table2.values

                    if self.markers == 2:  # If the checkbox is checked - markers will be plotted, just a line #MacOSX fix1
                        p[j], = ax.plot(table2.x,
                                        table2.y1,
                                        marker='o',
                                        linestyle='-',
                                        label=obsid)  # PLOT!!
                    else:
                        p[j], = ax.plot(table2.x,
                                        table2.y1,
                                        marker='None',
                                        linestyle='-',
                                        label=obsid)  # PLOT!!
                    plabel[j] = obsid + str(
                        self.y1col)  #+ str(j)# Label for the plot #MacOSX fix1
                    if len(self.y2col):
                        j = j + 1
                        if self.markers == 2:  # If the checkbox is checked - markers will be plotted, just a line #MacOSX fix1
                            p[j], = ax.plot(table2.x,
                                            table2.y2,
                                            marker='o',
                                            linestyle='-',
                                            label=obsid)  # PLOT!!
                        else:
                            p[j], = ax.plot(table2.x,
                                            table2.y2,
                                            marker='None',
                                            linestyle='-',
                                            label=obsid)  # PLOT!!
                        plabel[j] = obsid + str(
                            self.y2col
                        )  #+ str(j)# Label for the plot #MacOSX fix1
                    if len(self.y3col):
                        j = j + 1
                        if self.markers == 2:  # If the checkbox is checked - markers will be plotted, just a line #MacOSX fix1
                            p[j], = ax.plot(table2.x,
                                            table2.y3,
                                            marker='o',
                                            linestyle='-',
                                            label=obsid)  # PLOT!!
                        else:
                            p[j], = ax.plot(table2.x,
                                            table2.y3,
                                            marker='None',
                                            linestyle='-',
                                            label=obsid)  # PLOT!!
                        plabel[j] = obsid + str(
                            self.y3col
                        )  #+ str(j)# Label for the plot #MacOSX fix1
                    j = j + 1
                """ Finish plot """
                ax.grid(True)
                ax.yaxis.set_major_formatter(
                    tick.ScalarFormatter(useOffset=False, useMathText=False))
                ax.set_xlabel(self.xcol)  #MacOSX fix1
                ylabel = str(self.y1col) + ", \n" + str(
                    self.y2col) + ", \n" + str(self.y3col)  #MacOSX fix1
                ax.set_ylabel(ylabel)
                ax.set_title(self.settingsdict['xytable'])  #MacOSX fix1
                leg = fig.legend(p, plabel, loc=0)
                leg.draggable(state=True)
                frame = leg.get_frame(
                )  # the matplotlib.patches.Rectangle instance surrounding the legend
                frame.set_facecolor(
                    '0.80')  # set the frame face color to light gray
                frame.set_fill(False)  # set the frame face color transparent
                for t in leg.get_texts():
                    t.set_fontsize(10)  # the legend text fontsize
                for label in ax.xaxis.get_ticklabels():
                    label.set_fontsize(10)
                for label in ax.yaxis.get_ticklabels():
                    label.set_fontsize(10)
                fig.show(
                )  # causes conflict with plugins "statist" and "chartmaker"
            else:
                utils.pop_up_info(
                    ru(
                        QCoreApplication.translate(
                            'XYPlot',
                            "Please select at least one point with xy data")))
        else:
            utils.pop_up_info(
                ru(
                    QCoreApplication.translate(
                        'XYPlot',
                        "Please select a layer containing observations with xy data"
                    )))
Esempio n. 46
0
            return
        if os.path.splitext(filename)[1] != u'.csv':
            filename += u'.csv'
        try:
            with open(filename, 'w') as f:
                f.write(u'\n'.join(printlist).encode('utf-8'))
        except IOError, e:
            utils.pop_up_info(
                ru(
                    QCoreApplication.translate(
                        u'ExportToFieldLogger',
                        u"Writing of file failed!: %s ")) % str(e))
        except UnicodeDecodeError, e:
            utils.pop_up_info(
                ru(
                    QCoreApplication.translate(u'ExportToFieldLogger',
                                               u"Error writing %s")) %
                str(printlist))


class ParameterGroup(object):
    def __init__(self, connect):
        """
        """
        #Widget list:

        self._location_suffix = PyQt4.QtGui.QLineEdit()
        self._sublocation_suffix = PyQt4.QtGui.QLineEdit()
        self._input_field_group_list = ExtendedQPlainTextEdit(
            keep_sorted=False)
        self._obsid_list = ExtendedQPlainTextEdit(keep_sorted=True)
    def __init__(self, settingsdict, num_data_cols, rowheader_colwidth_percent,
                 empty_row_between_tables, page_break_between_tables,
                 from_active_layer, sql_table):
        #show the user this may take a long time...
        utils.start_waiting_cursor()

        self.nr_header_rows = 3

        reportfolder = os.path.join(QDir.tempPath(), 'midvatten_reports')
        if not os.path.exists(reportfolder):
            os.makedirs(reportfolder)
        reportpath = os.path.join(reportfolder, "w_qual_report.html")
        f = codecs.open(reportpath, "wb", "utf-8")

        #write some initiating html
        rpt = r"""<head><title>%s</title></head>""" % ru(
            QCoreApplication.translate(
                'Wqualreport',
                'water quality report from Midvatten plugin for QGIS'))
        rpt += r""" <meta http-equiv="content-type" content="text/html; charset=utf-8" />"""  #NOTE, all report data must be in 'utf-8'
        rpt += "<html><body>"
        f.write(rpt)

        if from_active_layer:
            utils.pop_up_info(
                ru(
                    QCoreApplication.translate(
                        'CompactWqualReport',
                        'Check that exported number of rows are identical to expected number of rows!\nFeatures in layers from sql queries can be invalid and then excluded from the report!'
                    )), 'Warning!')
            w_qual_lab_layer = qgis.utils.iface.activeLayer()
            if w_qual_lab_layer is None:
                raise utils.UsageError(
                    ru(
                        QCoreApplication.translate('CompactWqualReport',
                                                   'Must select a layer!')))
            if not w_qual_lab_layer.selectedFeatureCount():
                w_qual_lab_layer.selectAll()
            data = self.get_data_from_qgislayer(w_qual_lab_layer)
        else:
            data = self.get_data_from_sql(sql_table,
                                          utils.getselectedobjectnames())

        report_data, num_data = self.data_to_printlist(data)
        utils.MessagebarAndLog.info(bar_msg=ru(
            QCoreApplication.translate(
                'CompactWqualReport',
                'Created report from %s number of rows.')) % str(num_data))

        for startcol in range(1, len(report_data[0]), num_data_cols):
            printlist = [[row[0]] for row in report_data]
            for rownr, row in enumerate(report_data):
                printlist[rownr].extend(
                    row[startcol:min(startcol + num_data_cols, len(row))])

            filtered = [row for row in printlist if any(row[1:])]

            self.htmlcols = len(filtered[0])
            self.WriteHTMLReport(
                filtered,
                f,
                rowheader_colwidth_percent,
                empty_row_between_tables=empty_row_between_tables,
                page_break_between_tables=page_break_between_tables)

        # write some finishing html and close the file
        f.write("\n</body></html>")
        f.close()

        utils.stop_waiting_cursor(
        )  # now this long process is done and the cursor is back as normal

        if report_data:
            QDesktopServices.openUrl(QUrl.fromLocalFile(reportpath))
    def parse(self, filenames):
        """ Reads the interlab
        :param filenames:
        :return: A dict like {<lablittera>: {'metadata': {'metadataheader': value, ...}, <par1_name>: {'dataheader': value, ...}}}
        """
        all_lab_results = {}

        for filename in filenames:
            file_settings = self.parse_filesettings(filename)
            file_error, version, encoding, decimalsign, quotechar = file_settings
            if file_error:
                utils.pop_up_info(
                    ru(
                        QCoreApplication.translate(
                            'Interlab4Import',
                            "Warning: The file information %s could not be read. Skipping file"
                        )) % filename)
                continue

            with io.open(filename, 'r', encoding=encoding) as f:
                if quotechar:
                    unicode_reader = csv.reader(f,
                                                dialect=csv.excel,
                                                quotechar=str(quotechar),
                                                delimiter=';')
                else:
                    unicode_reader = csv.reader(f,
                                                dialect=csv.excel,
                                                delimiter=';')

                lab_results = {}
                file_error = False
                read_metadata_header = False
                parse_metadata_values = False
                read_data_header = False
                parse_data_values = False

                metadata_header = None
                data_header = None

                for cols in unicode_reader:
                    if not cols:
                        continue

                    if cols[0].lower().startswith('#s**t'):
                        break

                    #cols = ru(cols, keep_containers=True)

                    if cols[0].lower().startswith('#provadm'):
                        parse_data_values = False
                        parse_metadata_values = False
                        read_data_header = False
                        read_metadata_header = True
                        data_header = None
                        metadata_header = None
                        continue

                    if cols[0].lower().startswith('#provdat'):
                        parse_data_values = False
                        parse_metadata_values = False
                        read_metadata_header = False
                        read_data_header = True
                        continue

                    if read_metadata_header:
                        metadata_header = [x.lower() for x in cols]
                        read_metadata_header = False
                        parse_metadata_values = True
                        continue

                    if parse_metadata_values:
                        metadata = dict([(metadata_header[idx],
                                          value.lstrip(' ').rstrip(' '))
                                         for idx, value in enumerate(cols)
                                         if value.lstrip(' ').rstrip(' ')])
                        lab_results.setdefault(metadata['lablittera'],
                                               {})['metadata'] = metadata
                        continue

                    if read_data_header:
                        data_header = [x.lower() for x in cols]
                        read_data_header = False
                        parse_data_values = True
                        continue

                    if parse_data_values:
                        data = dict([(data_header[idx],
                                      value.lstrip(' ').rstrip(' '))
                                     for idx, value in enumerate(cols)
                                     if value.lstrip(' ').rstrip(' ')])
                        if 'mätvärdetal' in data:
                            data['mätvärdetal'] = data['mätvärdetal'].replace(
                                decimalsign, '.')

                        if not 'parameter' in data:
                            utils.pop_up_info(
                                ru(
                                    QCoreApplication.translate(
                                        'Interlab4Import',
                                        "WARNING: Parsing error. The parameter is missing on row %s"
                                    )) % str(cols))
                            continue

                        if data['lablittera'] not in lab_results:
                            utils.pop_up_info(
                                ru(
                                    QCoreApplication.translate(
                                        'Interlab4Import',
                                        "WARNING: Parsing error. Data for %s read before it's metadata."
                                    )) % data['lablittera'])
                            file_error = True
                            break

                        # If two parameter with the same name exists in the report, use the highest resolution one, that is, the one with the lowest value.
                        existing_data = lab_results[data['lablittera']].get(
                            data['parameter'], None)
                        if existing_data is not None:
                            primary_data, _duplicate_data = self.compare_duplicate_parameters(
                                data, existing_data)

                            lab_results[data['lablittera']][
                                data['parameter']] = primary_data

                            dupl_index = 1
                            duplicate_parname = _duplicate_data['parameter']
                            while duplicate_parname in lab_results[
                                    data['lablittera']]:
                                duplicate_translation = 'dubblett' if utils.getcurrentlocale(
                                )[0] == 'sv_SE' else 'duplicate'
                                duplicate_parname = '%s (%s %s)' % (
                                    _duplicate_data['parameter'],
                                    duplicate_translation, str(dupl_index))
                                dupl_index += 1
                            else:
                                _duplicate_data[
                                    'parameter'] = duplicate_parname
                                lab_results[data['lablittera']][
                                    _duplicate_data[
                                        'parameter']] = _duplicate_data

                            continue

                        lab_results[data['lablittera']][
                            data['parameter']] = data

                if not file_error:
                    all_lab_results.update(lab_results)

        return all_lab_results