Ejemplo n.º 1
0
 def test_get_distance(self):
     coordinates_distance = [
         (50.355136, 7.566077, 50.353968, 4.577915, 212),
         (-5.135943, -42.792442, 4.606085, 120.028077, 18130)
     ]
     for lat0, lon0, lat1, lon1, distance in coordinates_distance:
         assert int(coordinate.get_distance(lat0, lon0, lat1,
                                            lon1)) == distance
Ejemplo n.º 2
0
    def compute_solar_lines(self, bmap, wp_vertices, wp_heights, wp_times, solartype):
        """
        Computes coloured overlay over the flight path that indicates
        the danger of looking into the sun with a limb sounder aboard
        the aircraft.

        Args:
            bmap: Projection of TopView
            wp_vertices: waypoints of the flight path
            wp_heights: altitude of the waypoints of flight path

        Returns: LineCollection of coloured lines according to the
                 angular distance between viewing direction and solar
                 angle
        """
        # calculate distances and times
        body, difftype = solartype

        times = [datetime_to_jsec(_wp_time) for _wp_time in wp_times]
        x, y = list(zip(*wp_vertices))
        wp_lons, wp_lats = bmap(x, y, inverse=True)

        fine_lines = [bmap.gcpoints2(wp_lons[i], wp_lats[i], wp_lons[i + 1], wp_lats[i + 1], map_coords=False) for i in
                      range(len(wp_lons) - 1)]
        line_heights = [np.linspace(wp_heights[i], wp_heights[i + 1], num=len(fine_lines[i][0])) for i in
                        range(len(fine_lines))]
        line_times = [np.linspace(times[i], times[i + 1], num=len(fine_lines[i][0])) for i in
                      range(len(fine_lines))]
        # fine_lines = list of tuples with x-list and y-list for each segment
        # lines = list of tuples with lon-list and lat-list for each segment
        heights = []
        times = []
        for i in range(len(fine_lines) - 1):
            heights.extend(line_heights[i][:-1])
            times.extend(line_times[i][:-1])
        heights.extend(line_heights[-1])
        times.extend(line_times[-1])
        solar_x = []
        solar_y = []
        for i in range(len(fine_lines) - 1):
            solar_x.extend(fine_lines[i][0][:-1])
            solar_y.extend(fine_lines[i][1][:-1])
        solar_x.extend(fine_lines[-1][0])
        solar_y.extend(fine_lines[-1][1])
        points = []
        old_wp = None
        total_distance = 0
        for i, (lon, lat) in enumerate(zip(solar_x, solar_y)):
            points.append([[lon, lat]])  # append double-list for later concatenation
            if old_wp is not None:
                wp_dist = get_distance(old_wp[0], old_wp[1], lat, lon) * 1000.
                total_distance += wp_dist
            old_wp = (lat, lon)
        vals = []
        for i in range(len(points) - 1):
            p0, p1 = points[i][0], points[i + 1][0]

            sol_azi, sol_ele = self.compute_body_angle(body, times[i], p0[0], p0[1])
            obs_azi, obs_ele = self.compute_view_angles(
                p0[0], p0[1], heights[i], p1[0], p1[1], heights[i + 1],
                self.dsbObsAngleAzimuth.value(), self.dsbObsAngleElevation.value())
            if sol_azi < 0:
                sol_azi += 360
            if obs_azi < 0:
                obs_azi += 360
            rating = self.calc_view_rating(obs_azi, obs_ele, sol_azi, sol_ele, heights[i], difftype)
            vals.append(rating)

        # convert lon, lat to map points
        for i in range(len(points)):
            points[i][0][0], points[i][0][1] = bmap(points[i][0][0], points[i][0][1])
        points = np.concatenate([points[:-1], points[1:]], axis=1)
        # plot
        solar_lines = LineCollection(points, cmap=self.solar_cmap, norm=self.solar_norm,
                                     zorder=2, linewidths=3, animated=True)
        solar_lines.set_array(np.array(vals))
        return solar_lines
Ejemplo n.º 3
0
    def update_distances(self, position, rows=1):
        """
        Update all distances in a flight track that are affected by a
        waypoint change involving <rows> waypoints starting at index
        <position>.

        Distances are computed along great circles.

        If rows=1, the distance to the previous waypoint is updated for
        waypoints <position> and <position+1>. The total flight track distance
        is updated for all waypoint following <position>.

        If rows>1, the distances to the previous waypoints are updated
        according to the number of modified waypoints.
        """
        waypoints = self.waypoints
        aircraft = self.performance_settings["aircraft"]

        def get_duration_fuel(flightlevel0, flightlevel1, distance, weight,
                              lastleg):
            if flightlevel0 == flightlevel1:
                tas, fuelflow = aircraft.get_cruise_performance(
                    flightlevel0 * 100, weight)
                duration = 3600. * distance / (
                    1.852 * tas)  # convert to s (tas is in nm/h)
                leg_fuel = duration * fuelflow / 3600.
                return duration, leg_fuel
            else:
                if flightlevel0 < flightlevel1:
                    duration0, dist0, fuel0 = aircraft.get_climb_performance(
                        flightlevel0 * 100, weight)
                    duration1, dist1, fuel1 = aircraft.get_climb_performance(
                        flightlevel1 * 100, weight)
                else:
                    duration0, dist0, fuel0 = aircraft.get_descent_performance(
                        flightlevel0 * 100, weight)
                    duration1, dist1, fuel1 = aircraft.get_descent_performance(
                        flightlevel1 * 100, weight)
                duration = (duration1 -
                            duration0) * 60  # convert from min to s
                dist = (dist1 - dist0) * 1.852  # convert from nm to km
                fuel = fuel1 - fuel0
                if lastleg:
                    duration_p, fuel_p = get_duration_fuel(
                        flightlevel0, flightlevel0, distance - dist, weight,
                        False)
                else:
                    duration_p, fuel_p = get_duration_fuel(
                        flightlevel1, flightlevel1, distance - dist, weight,
                        False)
                return duration + duration_p, fuel + fuel_p

        pos = position
        for offset in range(rows):
            pos = position + offset
            wp1 = waypoints[pos]
            # The distance to the first waypoint is zero.
            if pos == 0:
                wp1.distance_to_prev = 0.
                wp1.distance_total = 0.

                wp1.leg_time = 0  # time from previous waypoint
                wp1.cum_time = 0  # total time of flight
                wp1.utc_time = self.performance_settings[
                    "takeoff_time"].toPyDateTime()
                wp1.weight = self.performance_settings["takeoff_weight"]
                wp1.leg_fuel = 0
                wp1.rem_fuel = self.performance_settings[
                    "takeoff_weight"] - self.performance_settings[
                        "empty_weight"]
                wp1.ascent_rate = 0
            else:
                wp0 = waypoints[pos - 1]
                wp1.distance_to_prev = get_distance(wp0.lat, wp0.lon, wp1.lat,
                                                    wp1.lon)

                last = (pos - 1 == rows)
                time, fuel = get_duration_fuel(wp0.flightlevel,
                                               wp1.flightlevel,
                                               wp1.distance_to_prev,
                                               wp0.weight,
                                               lastleg=last)
                wp1.leg_time = time
                wp1.cum_time = wp0.cum_time + wp1.leg_time
                wp1.utc_time = wp0.utc_time + datetime.timedelta(
                    seconds=wp1.leg_time)
                wp1.leg_fuel = fuel
                wp1.rem_fuel = wp0.rem_fuel - wp1.leg_fuel
                wp1.weight = wp0.weight - wp1.leg_fuel
                if wp1.leg_time != 0:
                    wp1.ascent_rate = int((wp1.flightlevel - wp0.flightlevel) *
                                          100 / (wp1.leg_time / 60))
                else:
                    wp1.ascent_rate = 0
            wp1.ceiling_alt = aircraft.get_ceiling_altitude(wp1.weight)

        # Update the distance of the following waypoint as well.
        if pos < len(waypoints) - 1:
            wp2 = waypoints[pos + 1]
            wp2.distance_to_prev = get_distance(wp1.lat, wp1.lon, wp2.lat,
                                                wp2.lon)
            if wp2.leg_time != 0:
                wp2.ascent_rate = int((wp2.flightlevel - wp1.flightlevel) *
                                      100 / (wp2.leg_time / 60))
            else:
                wp2.ascent_rate = 0

        # Update total distances of waypoint at index position and all
        # following waypoints.
        for i in range(max(min(position, 1), 1), len(waypoints)):
            wp0 = waypoints[i - 1]
            wp1 = waypoints[i]
            wp1.distance_total = wp0.distance_total + wp1.distance_to_prev
            wp1.weight = wp0.weight - wp0.leg_fuel
            last = (i + 1 == len(waypoints))
            time, fuel = get_duration_fuel(wp0.flightlevel,
                                           wp1.flightlevel,
                                           wp1.distance_to_prev,
                                           wp0.weight,
                                           lastleg=last)

            wp1.leg_time = time
            wp1.cum_time = wp0.cum_time + wp1.leg_time
            wp1.utc_time = wp0.utc_time + datetime.timedelta(
                seconds=wp1.leg_time)
            wp1.leg_fuel = fuel
            wp1.rem_fuel = wp0.rem_fuel - wp1.leg_fuel
            wp1.weight = wp0.weight - wp1.leg_fuel
            wp1.ceiling_alt = aircraft.get_ceiling_altitude(wp1.weight)

        index1 = self.createIndex(0, TIME_UTC)
        self.dataChanged.emit(index1, index1)