示例#1
0
    def redraw_yaxis(self):
        """ Redraws the y-axis on map after setting the values from sideview options dialog box"""

        self.checknconvert()
        vaxis = self.settings_dict["vertical_axis"]
        if vaxis == "pressure":
            # Compute the position of major and minor ticks. Major ticks are labelled.
            major_ticks = self._pres_maj[(self._pres_maj <= self.p_bot) & (self._pres_maj >= self.p_top)]
            minor_ticks = self._pres_min[(self._pres_min <= self.p_bot) & (self._pres_min >= self.p_top)]
            labels = [f"{int(_x / 100)}"
                      if (_x / 100) - int(_x / 100) == 0 else f"{float(_x / 100)}" for _x in major_ticks]
            if len(labels) > 20:
                labels = ["" if x.split(".")[-1][0] in "975" else x for x in labels]
            elif len(labels) > 10:
                labels = ["" if x.split(".")[-1][0] in "9" else x for x in labels]
            self.ax.set_ylabel("pressure (hPa)")
        elif vaxis == "pressure altitude":
            bot_km = thermolib.pressure2flightlevel(self.p_bot) * 0.03048
            top_km = thermolib.pressure2flightlevel(self.p_top) * 0.03048
            ma_dist, mi_dist = 4, 1.0
            if (top_km - bot_km) <= 20:
                ma_dist, mi_dist = 1, 0.5
            elif (top_km - bot_km) <= 40:
                ma_dist, mi_dist = 2, 0.5
            major_heights = np.arange(0, top_km + 1, ma_dist)
            minor_heights = np.arange(0, top_km + 1, mi_dist)
            major_ticks = thermolib.flightlevel2pressure_a(major_heights / 0.03048)
            minor_ticks = thermolib.flightlevel2pressure_a(minor_heights / 0.03048)
            labels = major_heights
            self.ax.set_ylabel("pressure altitude (km)")
        elif vaxis == "flight level":
            bot_km = thermolib.pressure2flightlevel(self.p_bot) * 0.03048
            top_km = thermolib.pressure2flightlevel(self.p_top) * 0.03048
            ma_dist, mi_dist = 50, 10
            if (top_km - bot_km) <= 10:
                ma_dist, mi_dist = 20, 10
            elif (top_km - bot_km) <= 40:
                ma_dist, mi_dist = 40, 10
            major_fl = np.arange(0, 2132, ma_dist)
            minor_fl = np.arange(0, 2132, mi_dist)
            major_ticks = thermolib.flightlevel2pressure_a(major_fl)
            minor_ticks = thermolib.flightlevel2pressure_a(minor_fl)
            labels = major_fl
            self.ax.set_ylabel("flight level (hft)")
        else:
            raise RuntimeError("Unsupported vertical axis type: '{}'".format(vaxis))

        # Draw ticks and tick labels.
        self.ax.set_yticks(minor_ticks, minor=True)
        self.ax.set_yticks(major_ticks, minor=False)
        self.ax.set_yticklabels([], minor=True, fontsize=10)
        self.ax.set_yticklabels(labels, minor=False, fontsize=10)
        self.ax.set_ylim(self.p_bot, self.p_top)
示例#2
0
文件: utils.py 项目: jukiforde/MSS
def convert_pressure_to_vertical_axis_measure(vertical_axis, pressure):
    """
    vertical_axis can take following values
    - pressure altitude
    - flight level
    - pressure
    """
    if vertical_axis == "pressure":
        return float(pressure / 100)
    elif vertical_axis == "flight level":
        return pressure2flightlevel(pressure)
    elif vertical_axis == "pressure altitude":
        return pressure2flightlevel(pressure) / 32.8
    else:
        return pressure
示例#3
0
def test_pressure2flightlevel():
    assert tl.pressure2flightlevel(50000.) == pytest.approx(182.8850)
    assert tl.pressure2flightlevel(10000.) == pytest.approx(530.8279)
    assert tl.pressure2flightlevel(3000.) == pytest.approx(782.4335)
    assert tl.pressure2flightlevel(550.) == pytest.approx(1151.9583)
    assert tl.pressure2flightlevel(80.) == pytest.approx(1626.8966)
    assert tl.pressure2flightlevel(40.) == pytest.approx(1804.2727)
    with pytest.raises(ValueError):
        tl.pressure2flightlevel(3.9)
    pss = np.arange(5., 100000., 100.)
    assert np.allclose([tl.pressure2flightlevel(_x) for _x in pss],
                       tl.pressure2flightlevel_a(pss))
示例#4
0
def test_pressure2flightlevel():
    assert tl.pressure2flightlevel(50000) == pytest.approx(182.89130205844737)
    assert tl.pressure2flightlevel(10000) == pytest.approx(530.8390754393636)
    assert tl.pressure2flightlevel(3000) == pytest.approx(782.4486256345779)
    assert tl.pressure2flightlevel(550) == pytest.approx(1151.9849776810745)
    assert tl.pressure2flightlevel(80) == pytest.approx(1626.9512858549855)
    assert tl.pressure2flightlevel(40) == pytest.approx(1804.3261490037305)
    with pytest.raises(ValueError):
        tl.pressure2flightlevel(3.9)
    pss = np.arange(5., 100000., 100.)
    assert np.allclose([tl.pressure2flightlevel(_x) for _x in pss],
                       tl.pressure2flightlevel_a(pss))
示例#5
0
    def button_release_insert_callback(self, event):
        """Called whenever a mouse button is released.

        From the click event's coordinates, best_index is calculated as
        the index of a vertex whose x coordinate > clicked x coordinate.
        This is the position where the waypoint is to be inserted.

        'lat' and 'lon' are calculated as an average of each of the first waypoint
        in left and right neighbourhood of inserted waypoint.

        The coordinates are checked against "locations" defined in mss' config.

        A new waypoint with the coordinates, and name is inserted into the waypoints_model.
        """
        if not self.showverts or event.button != 1 or event.inaxes is None:
            return
        y = event.ydata
        wpm = self.waypoints_model
        flightlevel = float(pressure2flightlevel(y))
        [lat, lon], best_index = self.get_lat_lon(event)
        loc = find_location(
            lat, lon)  # skipped tolerance which uses appropriate_epsilon_km
        if loc is not None:
            (lat, lon), location = loc
        else:
            location = ""
        new_wp = ft.Waypoint(lat, lon, flightlevel, location=location)
        wpm.insertRows(best_index, rows=1, waypoints=[new_wp])
        self.redraw_figure()

        self._ind = 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 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())
示例#8
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