示例#1
0
def load_from_txt(filename):
    name = os.path.basename(filename.replace(".txt", "").strip())
    waypoints = []
    _dirname, _name = os.path.split(filename)
    _fs = open_fs(_dirname)
    with _fs.open(_name, "r") as in_file:
        pos = []
        for line in in_file:
            if line.startswith("#"):
                continue
            if line.startswith("Index"):
                pos.append(0)  # 0
                pos.append(line.find("Location"))  # 1
                pos.append(line.find("Lat (+-90)"))  # 2
                pos.append(line.find("Lon (+-180)"))  # 3
                pos.append(line.find("Flightlevel"))  # 4
                pos.append(line.find("Pressure (hPa)"))  # 5
                pos.append(line.find("Leg dist. (km)"))  # 6
                pos.append(line.find("Cum. dist. (km)"))  # 7
                pos.append(line.find("Comments"))  # 8
                continue
            if line.startswith("Track name: "):
                continue

            if len(pos) == 0:
                raise SyntaxError(
                    "TXT Import could not parse column headings.")
            if len(line) < max(pos):
                raise SyntaxError(f"TXT Import could not parse line: '{line}'")

            wp = ft.Waypoint()
            attr_names = [
                "location", "lat", "lon", "flightlevel", "pressure",
                "distance_to_prev", "distance_total", "comments"
            ]
            setattr(wp, attr_names[0], line[pos[1]:pos[2]].strip())
            setattr(wp, attr_names[7], line[pos[8]:].strip())
            for i in range(2, len(pos) - 1):
                if pos[i] >= 0:
                    if i == 5:
                        setattr(wp, attr_names[i - 1],
                                float(line[pos[i]:pos[i + 1]].strip()) * 100.)
                    else:
                        setattr(wp, attr_names[i - 1],
                                float(line[pos[i]:pos[i + 1]].strip()))
                else:
                    if i == 5:
                        logging.debug('calculate pressure from FL ' + str(
                            thermolib.flightlevel2pressure(
                                float(wp.flightlevel))))
                        setattr(
                            wp, attr_names[i - 1],
                            thermolib.flightlevel2pressure(
                                float(wp.flightlevel)))
            waypoints.append(wp)
    return name, waypoints
示例#2
0
    def checknconvert(self):
        """ Checks for current units of axis and convert the upper and lower limit
        to pa(pascals) for the internal computation by code """

        if self.settings_dict["vertical_axis"] == "pressure altitude":
            self.p_bot = thermolib.flightlevel2pressure(self.settings_dict["vertical_extent"][0] * 32.80)
            self.p_top = thermolib.flightlevel2pressure(self.settings_dict["vertical_extent"][1] * 32.80)
        elif self.settings_dict["vertical_axis"] == "flight level":
            self.p_bot = thermolib.flightlevel2pressure(self.settings_dict["vertical_extent"][0])
            self.p_top = thermolib.flightlevel2pressure(self.settings_dict["vertical_extent"][1])
示例#3
0
def test_flightlevel2pressure():
    assert tl.flightlevel2pressure(182.8850) == pytest.approx(50000)
    assert tl.flightlevel2pressure(530.8279) == pytest.approx(10000)
    assert tl.flightlevel2pressure(782.4335) == pytest.approx(3000)
    assert tl.flightlevel2pressure(1151.9583) == pytest.approx(550)
    assert tl.flightlevel2pressure(1626.8966) == pytest.approx(80)
    assert tl.flightlevel2pressure(1804.2727) == pytest.approx(40)
    with pytest.raises(ValueError):
        tl.flightlevel2pressure(72000 / 30.48)
    fls = np.arange(0, 71000, 1000) / 30.48
    assert np.allclose([tl.flightlevel2pressure(_x) for _x in fls],
                       tl.flightlevel2pressure_a(fls))
示例#4
0
def test_flightlevel2pressure():
    assert tl.flightlevel2pressure(182.8913020844737) == pytest.approx(50000)
    assert tl.flightlevel2pressure(530.8390754393636) == pytest.approx(10000)
    assert tl.flightlevel2pressure(782.4486256345779) == pytest.approx(3000)
    assert tl.flightlevel2pressure(1151.9849776810745) == pytest.approx(550)
    assert tl.flightlevel2pressure(1626.9512858549855) == pytest.approx(80)
    assert tl.flightlevel2pressure(1804.3261490037305) == pytest.approx(40)
    with pytest.raises(ValueError):
        tl.flightlevel2pressure(72000 / 30.48)
    fls = np.arange(0, 71000, 1000) / 30.48
    assert np.allclose([tl.flightlevel2pressure(_x) for _x in fls],
                       tl.flightlevel2pressure_a(fls))
示例#5
0
    def __init__(self, lat=0, lon=0, flightlevel=0, location="", comments=""):
        self.location = location
        locations = config_loader(dataset='locations',
                                  default=mss_default.locations)
        if location in locations:
            self.lat, self.lon = locations[location]
        else:
            self.lat = lat
            self.lon = lon
        self.flightlevel = flightlevel
        self.pressure = thermolib.flightlevel2pressure(flightlevel)
        self.distance_to_prev = 0.
        self.distance_total = 0.
        self.comments = comments

        # Performance fields (for values read from the flight performance
        # service).
        self.leg_time = None  # time from previous waypoint
        self.cum_time = None  # total time of flight
        self.utc_time = None  # time in UTC since given takeoff time
        self.leg_fuel = None  # fuel consumption since previous waypoint
        self.rem_fuel = None  # total fuel consumption
        self.weight = None  # aircraft gross weight
        self.ceiling_alt = None  # aircraft ceiling altitude
        self.ascent_rate = None  # aircraft ascent rate

        self.wpnumber_major = None
        self.wpnumber_minor = None
示例#6
0
 def verticalunitsclicked(self, index):
     units = {
         "pressure": "hPa",
         "pressure altitude": "km",
         "flight level": "hft"
     }
     _translate = QtCore.QCoreApplication.translate
     unit = units[self.cbVerticalAxis.model().itemFromIndex(index).text()]
     currentunit = units[self.cbVerticalAxis.currentText()]
     if unit == currentunit:
         return
     self.setBotTopLimits("maximum")
     self.sbPbot.setSuffix(_translate("SideViewOptionsDialog", " " + unit))
     self.sbPtop.setSuffix(_translate("SideViewOptionsDialog", " " + unit))
     if unit == "hPa":
         self.sbPtop.setValue(
             thermolib.flightlevel2pressure(
                 convert_to(self.sbPtop.value(), currentunit, "hft", 1)) /
             100)
         self.sbPbot.setValue(
             thermolib.flightlevel2pressure(
                 convert_to(self.sbPbot.value(), currentunit, "hft", 1)) /
             100)
     elif currentunit == "hPa":
         self.sbPtop.setValue(
             convert_to(
                 thermolib.pressure2flightlevel(self.sbPtop.value() * 100),
                 "hft", unit))
         self.sbPbot.setValue(
             convert_to(
                 thermolib.pressure2flightlevel(self.sbPbot.value() * 100),
                 "hft", unit))
     else:
         self.sbPtop.setValue(
             convert_to(self.sbPtop.value(), currentunit, unit, 1))
         self.sbPbot.setValue(
             convert_to(self.sbPbot.value(), currentunit, unit, 1))
     self.setBotTopLimits(
         self.cbVerticalAxis.model().itemFromIndex(index).text())
示例#7
0
 def draw_flight_levels(self):
     """Draw horizontal lines indicating the altitude of the flight levels.
     """
     # Remove currently displayed flight level artists.
     for artist in self.fl_label_list:
         artist.remove()
     self.fl_label_list = []
     # Plot lines indicating flight level altitude.
     ax = self.ax
     for level in self.flightlevels:
         pressure = thermolib.flightlevel2pressure(level)
         self.fl_label_list.append(ax.axhline(pressure, color='k'))
         self.fl_label_list.append(ax.text(0.1, pressure, f"FL{level:d}"))
     self.draw()
示例#8
0
 def verticalunitsclicked(self, index):
     new_unit = self._suffixes[index]
     old_unit = self.sbPbot.suffix().strip()
     if new_unit == old_unit:
         return
     self.setBotTopLimits("maximum")
     for sb in (self.sbPbot, self.sbPtop):
         sb.setSuffix(" " + new_unit)
         if new_unit == "hPa":
             sb.setValue(thermolib.flightlevel2pressure(
                 convert_to(sb.value(), old_unit, "hft", 1)) / 100)
         elif old_unit == "hPa":
             sb.setValue(convert_to(
                 thermolib.pressure2flightlevel(sb.value() * 100), "hft", new_unit))
         else:
             sb.setValue(convert_to(sb.value(), old_unit, new_unit, 1))
     self.setBotTopLimits(self.cbVerticalAxis.currentText())
示例#9
0
def load_from_flitestar(filename):
    waypoints = []
    _dirname, _name = os.path.split(filename)
    _fs = open_fs(_dirname)
    with _fs.open(_name, 'r') as f:
        firstline = f.readline()
        if not firstline.startswith(
                "# FliteStar/FliteMap generated flight plan."):
            raise SyntaxError("The file does not seem to be a FliteStar file!")
        for line in f:

            if line.startswith('FWP'):
                line = line.split()
                if len(line) < 10:
                    raise SyntaxError(f"Line {line} has less than 9 fields.")
                alt = round(float(line[-1]) / 100., 2)
                if line[4] == 'N':
                    NS = 1.
                elif line[4] == 'S':
                    NS = -1.
                else:
                    NS = np.nan
                lat = round((float(line[5]) + (float(line[6]) / 60.)) * NS, 3)
                if line[7] == 'E':
                    EW = 1.
                elif line[7] == 'W':
                    EW = -1.
                else:
                    EW = np.nan
                lon = round((float(line[8]) + (float(line[9]) / 60.)) * EW, 3)

                wp = ft.Waypoint()
                wp.location = line[3]
                wp.lat = float(lat)
                wp.lon = float(lon)
                wp.flightlevel = float(alt)
                wp.pressure = thermolib.flightlevel2pressure(
                    float(wp.flightlevel))
                waypoints.append(wp)

    name = os.path.basename(filename).strip('.txt')
    return name, waypoints
示例#10
0
    def setData(self, index, value, role=QtCore.Qt.EditRole, update=True):
        """Change a data element of the flight track; overrides the
           corresponding QAbstractTableModel method.

        NOTE: Performance computations loose their validity if a change is made.
        """
        if index.isValid() and 0 <= index.row() < len(self.waypoints):
            waypoint = self.waypoints[index.row()]
            column = index.column()
            index2 = index  # in most cases only one field is being changed
            if column == LOCATION:
                waypoint.location = variant_to_string(value)
            elif column == LAT:
                try:
                    # The table fields accept basically any input.
                    # If the string cannot be converted to "float" (raises ValueError), the user input is discarded.
                    value = variant_to_float(value)
                except TypeError as ex:
                    logging.error("unexpected error: %s %s %s %s", type(ex),
                                  ex, type(value), value)
                except ValueError as ex:
                    logging.error("%s", ex)
                else:
                    waypoint.lat = value
                    waypoint.location = ""
                    loc = find_location(waypoint.lat, waypoint.lon, 1e-3)
                    if loc is not None:
                        waypoint.lat, waypoint.lon = loc[0]
                        waypoint.location = loc[1]
                    # A change of position requires an update of the distances.
                    if update:
                        self.update_distances(index.row())
                    # Notify the views that items between the edited item and
                    # the distance item of the corresponding waypoint have been
                    # changed.
                    # Delete the location name -- it won't be valid anymore
                    # after its coordinates have been changed.
                    index2 = self.createIndex(index.row(), LOCATION)
            elif column == LON:
                try:
                    # The table fields accept basically any input.
                    # If the string cannot be converted to "float" (raises ValueError), the user input is discarded.
                    value = variant_to_float(value)
                except TypeError as ex:
                    logging.error("unexpected error: %s %s %s %s", type(ex),
                                  ex, type(value), value)
                except ValueError as ex:
                    logging.error("%s", ex)
                else:
                    waypoint.lon = value
                    waypoint.location = ""
                    loc = find_location(waypoint.lat, waypoint.lon, 1e-3)
                    if loc is not None:
                        waypoint.lat, waypoint.lon = loc[0]
                        waypoint.location = loc[1]
                    if update:
                        self.update_distances(index.row())
                    index2 = self.createIndex(index.row(), LOCATION)
            elif column == FLIGHTLEVEL:
                try:
                    # The table fields accept basically any input.
                    # If the string cannot be converted to "float" (raises ValueError), the user input is discarded.
                    flightlevel = variant_to_float(value)
                    pressure = float(
                        thermolib.flightlevel2pressure(flightlevel))
                except TypeError as ex:
                    logging.error("unexpected error: %s %s %s %s", type(ex),
                                  ex, type(value), value)
                except ValueError as ex:
                    logging.error("%s", ex)
                else:
                    waypoint.flightlevel = flightlevel
                    waypoint.pressure = pressure
                    if update:
                        self.update_distances(index.row())
                    # need to notify view of the second item that has been
                    # changed as well.
                    index2 = self.createIndex(index.row(), PRESSURE)
            elif column == PRESSURE:
                try:
                    # The table fields accept basically any input.
                    # If the string cannot be converted to "float" (raises ValueError), the user input is discarded.
                    pressure = variant_to_float(
                        value) * 100  # convert hPa to Pa
                    if pressure > 200000:
                        raise ValueError
                    flightlevel = float(
                        round(thermolib.pressure2flightlevel(pressure)))
                    pressure = float(
                        thermolib.flightlevel2pressure(flightlevel))
                except TypeError as ex:
                    logging.error("unexpected error: %s %s %s %s", type(ex),
                                  ex, type(value), value)
                except ValueError as ex:
                    logging.error("%s", ex)
                else:
                    waypoint.pressure = pressure
                    waypoint.flightlevel = flightlevel
                    if update:
                        self.update_distances(index.row())
                    index2 = self.createIndex(index.row(), FLIGHTLEVEL)
            else:
                waypoint.comments = variant_to_string(value)
            self.modified = True
            # Performance computations loose their validity if a change is made.
            if update:
                self.dataChanged.emit(index, index2)
            return True
        return False