Saturday 18 May 2019

AviationLatLonCalculator enhancement: user can choose which CSV field is what

Fields from CSV file have been assigned to its values from CSV header file (e .g.  BRNG, DIST) inside the code so far. User has to prepare input file with 'correct' header - otherwise won't be able to perform calculations. And this is a big disadvantage.
Let's assume that we have following data set:

And we want possibility to assign CSV fields to variables that will be taken to perform calculations in the following way:


As you can see, the idea is to create QComboBox popup list from fields that are within header of CSV file. Next, we are going assign selected (current) value of QComboBox widget as a key for functions that reads rows of CSV files to get values of CSV fields corresponding to each row.
It sounds quite easy to add this functionality. Note, that at this stage I am not going to check if for all ComboBox widgets  (Name, Brng, etc.) selected fields are not the same. In other words, I am not going to check if for example Name and Dist have the same field chosen by user. It will be added in further enhancements.

First, after user select CSV file let's assign fields from header to ComboBox widgets:


if self.input_file != '':
    try:
        with open(self.input_file, 'r') as csv_data:
            reader = csv.DictReader(csv_data, delimiter=';')
            header = reader.fieldnames

        # Clear list in ComboBox widgets:
        self.dlg.comboBoxNameField.clear()
        self.dlg.comboBoxBrngField.clear()
        self.dlg.comboBoxDistField.clear()
        self.dlg.comboBoxDistUOMField.clear()

        # Add fields from CSV
        self.dlg.comboBoxNameField.addItems(header)
        self.dlg.comboBoxBrngField.addItems(header)
        self.dlg.comboBoxDistField.addItems(header)
        self.dlg.comboBoxDistUOMField.addItems(header)
    except:
        QMessageBox.critical(w, "Message", 'Can\'t read field from CSV file!')

Then, after open file, let's assign chosen values from ComboBox widgets as key for reader object to read values such as ID, BRNG, DIST, DIST_UOM:


point_id = self.dlg.comboBoxNameField.currentText()
azm_field = self.dlg.comboBoxBrngField.currentText()
dist_uom_field = self.dlg.comboBoxDistUOMField.currentText()
dist_field = self.dlg.comboBoxDistField.currentText()

Then, in loop while reading each line of data file let's create Bearing and Distance instance of object to check if input data are correct:

azm = agc.Bearing(row[azm_field])
dist_uom = row[dist_uom_field]
dist = agc.Distance(row[dist_field], dist_uom)

And do not forget to change line that is responisble for reading value of id point:

calc_point_id = row[point_id]

And that's all. You can easy calculate location of points given in 'aviation like' format for large data sets in more convenient way. And you will see the results on the map right after the input data file is processed.


No comments:

Post a Comment