def live_kml(cls, kml, timespan, resolution=100): """ Appends kml nodes describing current paths of the obstacles Args: kml: A simpleKML Container to which the obstacle data will be added timespan: A timedelta to look backwards in time resolution: integer number of milliseconds between obstacle positions Returns: None """ def track(obstacle, span, dt): curr = timezone.now() last = curr - span time = curr while time >= last: yield obstacle.get_position(time) time -= dt for obstacle in MovingObstacle.objects.all(): dt = timedelta(milliseconds=resolution) linestring = kml.newlinestring(name="Obstacle") coords = [] for pos in track(obstacle, timespan, dt): # Longitude, Latitude, Altitude coord = (pos[1], pos[0], units.feet_to_meters(pos[2])) coords.append(coord) linestring.coords = coords linestring.altitudemode = AltitudeMode.absolute linestring.extrude = 1 linestring.style.linestyle.color = Color.red linestring.style.polystyle.color = Color.changealphaint( 100, Color.red)
def kml(self, kml): """ Appends kml nodes describing this flyzone. Args: kml: A simpleKML Container to which the fly zone will be added """ zone_name = 'Fly Zone {}'.format(self.pk) pol = kml.newpolygon(name=zone_name) fly_zone = [] flyzone_num = 1 for point in self.boundary_pts.all(): gps = point.position.gps_position coord = (gps.longitude, gps.latitude, point.position.altitude_msl) fly_zone.append(coord) # Add boundary marker wp = kml.newpoint(name=str(flyzone_num), coords=[coord]) wp.description = str(point) wp.visibility = False flyzone_num += 1 fly_zone.append(fly_zone[0]) pol.outerboundaryis = fly_zone # Search Area Style pol.style.linestyle.color = Color.red pol.style.linestyle.width = 3 pol.style.polystyle.color = Color.changealphaint(50, Color.green)
def kml(self, kml): """ Appends kml nodes describing this flyzone. Args: kml: A simpleKML Container to which the fly zone will be added """ zone_name = 'Fly Zone {}'.format(self.pk) pol = kml.newpolygon(name=zone_name) fly_zone = [] flyzone_num = 1 for point in self.boundary_pts.all(): gps = point.position.gps_position coord = (gps.longitude, gps.latitude, units.feet_to_meters(point.position.altitude_msl)) fly_zone.append(coord) # Add boundary marker wp = kml.newpoint(name=str(flyzone_num), coords=[coord]) wp.description = str(point) wp.visibility = False flyzone_num += 1 fly_zone.append(fly_zone[0]) pol.outerboundaryis = fly_zone # Search Area Style pol.style.linestyle.color = Color.red pol.style.linestyle.width = 3 pol.style.polystyle.color = Color.changealphaint(50, Color.green)
def live_kml(cls, kml, timespan, resolution=100): """ Appends kml nodes describing current paths of the obstacles Args: kml: A simpleKML Container to which the obstacle data will be added timespan: A timedelta to look backwards in time resolution: integer number of milliseconds between obstacle positions Returns: None """ def track(obstacle, span, dt): curr = timezone.now() last = curr - span time = curr while time >= last: yield obstacle.get_position(time) time -= dt for obstacle in MovingObstacle.objects.all(): dt = timedelta(milliseconds=resolution) linestring = kml.newlinestring(name="Obstacle") coords = [] for pos in track(obstacle, timespan, dt): # Longitude, Latitude, Altitude coord = (pos[1], pos[0], pos[2]) coords.append(coord) linestring.coords = coords linestring.altitudemode = AltitudeMode.absolute linestring.extrude = 1 linestring.style.linestyle.color = Color.red linestring.style.polystyle.color = Color.changealphaint(100, Color.red)
def fly_zone_kml(fly_zone, kml): """ Appends kml nodes describing the flyzone. Args: fly_zone: The FlyZone for which to add KML kml: A simpleKML Container to which the fly zone will be added """ zone_name = 'Fly Zone {}'.format(fly_zone.pk) pol = kml.newpolygon(name=zone_name) fly_zone_points = [] for point in fly_zone.boundary_pts.order_by('order'): coord = (point.longitude, point.latitude, units.feet_to_meters(point.altitude_msl)) fly_zone_points.append(coord) fly_zone_points.append(fly_zone_points[0]) pol.outerboundaryis = fly_zone_points pol.style.linestyle.color = Color.red pol.style.linestyle.width = 3 pol.style.polystyle.color = Color.changealphaint(50, Color.green)
def kml(self, kml): """ Appends kml nodes describing this flyzone. Args: kml: A simpleKML Container to which the fly zone will be added """ zone_name = 'Fly Zone {}'.format(self.pk) pol = kml.newpolygon(name=zone_name) fly_zone = [] for point in self.boundary_pts.order_by('order'): gps = point.position.gps_position coord = (gps.longitude, gps.latitude, units.feet_to_meters(point.position.altitude_msl)) fly_zone.append(coord) fly_zone.append(fly_zone[0]) pol.outerboundaryis = fly_zone pol.style.linestyle.color = Color.red pol.style.linestyle.width = 3 pol.style.polystyle.color = Color.changealphaint(50, Color.green)
def live_kml(cls, kml, timespan): users = User.objects.all() for user in users: period_logs = UasTelemetry.by_user(user)\ .filter(timestamp__gt=timezone.now() - timespan) if len(period_logs) < 1: continue linestring = kml.newlinestring(name=user.username) coords = [] for entry in period_logs: pos = entry.uas_position.gps_position # Spatial Coordinates coord = (pos.longitude, pos.latitude, units.feet_to_meters(entry.uas_position.altitude_msl)) coords.append(coord) linestring.coords = coords linestring.altitudemode = AltitudeMode.absolute linestring.extrude = 1 linestring.style.linestyle.color = Color.blue linestring.style.polystyle.color = Color.changealphaint( 100, Color.blue)
def live_kml(cls, kml, timespan): users = User.objects.all() for user in users: period_logs = UasTelemetry.by_user(user)\ .filter(timestamp__gt=timezone.now() - timespan) if len(period_logs) < 1: continue linestring = kml.newlinestring(name=user.username) coords = [] for entry in period_logs: pos = entry.uas_position.gps_position # Spatial Coordinates coord = (pos.longitude, pos.latitude, units.feet_to_meters(entry.uas_position.altitude_msl)) coords.append(coord) linestring.coords = coords linestring.altitudemode = AltitudeMode.absolute linestring.extrude = 1 linestring.style.linestyle.color = Color.blue linestring.style.polystyle.color = Color.changealphaint(100, Color.blue)
def kml(self, kml): """ Appends kml nodes describing this mission configurations. Args: kml: A simpleKML Container to which the mission data will be added """ mission_name = "Mission {}".format(self.pk) kml_folder = kml.newfolder(name=mission_name) # Static Points locations = { "Home Position": self.home_pos, "Emergent LKP": self.emergent_last_known_pos, "Off Axis": self.off_axis_target_pos, "SRIC": self.sric_pos, "IR Primary": self.ir_primary_target_pos, "IR Secondary": self.ir_secondary_target_pos, "Air Drop": self.air_drop_pos, } for key, point in locations.iteritems(): gps = (point.longitude, point.latitude) wp = kml_folder.newpoint(name=key, coords=[gps]) wp.description = str(point) # Waypoints waypoints_folder = kml_folder.newfolder(name="Waypoints") linestring = waypoints_folder.newlinestring(name="Waypoints") waypoints = [] waypoint_num = 1 for waypoint in self.mission_waypoints.all(): gps = waypoint.position.gps_position coord = (gps.longitude, gps.latitude, waypoint.position.altitude_msl) waypoints.append(coord) # Add waypoint marker wp = waypoints_folder.newpoint(name=str(waypoint_num), coords=[coord]) wp.description = str(waypoint) wp.altitudemode = AltitudeMode.absolute wp.extrude = 1 wp.visibility = False waypoint_num += 1 linestring.coords = waypoints # Waypoints Style linestring.altitudemode = AltitudeMode.absolute linestring.extrude = 1 linestring.style.linestyle.color = Color.black linestring.style.polystyle.color = Color.changealphaint(100, Color.green) # Search Area search_area_folder = kml_folder.newfolder(name="Search Area") search_area = [] search_area_num = 1 for point in self.search_grid_points.all(): gps = point.position.gps_position coord = (gps.longitude, gps.latitude, point.position.altitude_msl) search_area.append(coord) # Add boundary marker wp = search_area_folder.newpoint(name=str(search_area_num), coords=[coord]) wp.description = str(point) wp.visibility = False search_area_num += 1 if search_area: # Create search area polygon. pol = search_area_folder.newpolygon(name="Search Area") search_area.append(search_area[0]) pol.outerboundaryis = search_area # Search Area Style. pol.style.linestyle.color = Color.black pol.style.linestyle.width = 2 pol.style.polystyle.color = Color.changealphaint(50, Color.blue) # Stationary Obstacles stationary_obstacles_folder = kml_folder.newfolder(name="Stationary Obstacles")
def kml(self, kml, kml_doc): """ Appends kml nodes describing this mission configurations. Args: kml: A simpleKML Container to which the mission data will be added kml_doc: The simpleKML Document to which schemas will be added """ mission_name = 'Mission {}'.format(self.pk) kml_folder = kml.newfolder(name=mission_name) # Static Points locations = { 'Home Position': self.home_pos, 'Emergent LKP': self.emergent_last_known_pos, 'Off Axis': self.off_axis_odlc_pos, 'Air Drop': self.air_drop_pos, } for key, point in locations.iteritems(): gps = (point.longitude, point.latitude) wp = kml_folder.newpoint(name=key, coords=[gps]) wp.description = str(point) # Waypoints waypoints_folder = kml_folder.newfolder(name='Waypoints') linestring = waypoints_folder.newlinestring(name='Waypoints') waypoints = [] waypoint_num = 1 for waypoint in self.mission_waypoints.order_by('order'): gps = waypoint.position.gps_position coord = (gps.longitude, gps.latitude, units.feet_to_meters(waypoint.position.altitude_msl)) waypoints.append(coord) # Add waypoint marker wp = waypoints_folder.newpoint(name=str(waypoint_num), coords=[coord]) wp.description = str(waypoint) wp.altitudemode = AltitudeMode.absolute wp.extrude = 1 wp.visibility = False waypoint_num += 1 linestring.coords = waypoints # Waypoints Style linestring.altitudemode = AltitudeMode.absolute linestring.extrude = 1 linestring.style.linestyle.color = Color.black linestring.style.polystyle.color = Color.changealphaint( 100, Color.green) # Search Area search_area_folder = kml_folder.newfolder(name='Search Area') search_area = [] search_area_num = 1 for point in self.search_grid_points.order_by('order'): gps = point.position.gps_position coord = (gps.longitude, gps.latitude, units.feet_to_meters(point.position.altitude_msl)) search_area.append(coord) # Add boundary marker wp = search_area_folder.newpoint(name=str(search_area_num), coords=[coord]) wp.description = str(point) wp.visibility = False search_area_num += 1 if search_area: # Create search area polygon. pol = search_area_folder.newpolygon(name='Search Area') search_area.append(search_area[0]) pol.outerboundaryis = search_area # Search Area Style. pol.style.linestyle.color = Color.black pol.style.linestyle.width = 2 pol.style.polystyle.color = Color.changealphaint(50, Color.blue) # Stationary Obstacles. stationary_obstacles_folder = kml_folder.newfolder( name='Stationary Obstacles') # TODO: Implement # Moving Obstacles. users = User.objects.all() moving_obstacle_periods = [] for user in users: moving_obstacle_periods.extend(TakeoffOrLandingEvent.flights(user)) moving_obstacles_folder = kml_folder.newfolder(name='Moving Obstacles') for obstacle in self.moving_obstacles.all(): obstacle.kml(moving_obstacle_periods, moving_obstacles_folder, kml_doc)
def mission_kml(mission, kml, kml_doc): """ Appends kml nodes describing the mission. Args: mission: The mission to add to the KML. kml: A simpleKML Container to which the mission data will be added kml_doc: The simpleKML Document to which schemas will be added Returns: The KML folder for the mission data. """ mission_name = 'Mission {}'.format(mission.pk) kml_folder = kml.newfolder(name=mission_name) # Transform from WGS84 to UTM at home position. wgs_to_utm = pyproj.transformer.Transformer.from_proj( distance.proj_wgs84, distance.proj_utm(mission.home_pos.latitude, mission.home_pos.longitude)) # Transform from WGS84 to Web Mercator. wgs_to_web_mercator = pyproj.transformer.Transformer.from_proj( distance.proj_wgs84, distance.proj_web_mercator) # Flight boundaries. fly_zone_folder = kml_folder.newfolder(name='Fly Zones') for flyzone in mission.fly_zones.all(): fly_zone_kml(flyzone, fly_zone_folder) # Static points. locations = [ ('Home', mission.home_pos, KML_HOME_ICON), ('Emergent LKP', mission.emergent_last_known_pos, KML_ODLC_ICON), ('Off Axis', mission.off_axis_odlc_pos, KML_ODLC_ICON), ('Air Drop', mission.air_drop_pos, KML_DROP_ICON), ('Map Center', mission.map_center_pos, KML_MAP_CENTER_ICON), ] for key, point, icon in locations: gps = (point.longitude, point.latitude) p = kml_folder.newpoint(name=key, coords=[gps]) p.iconstyle.icon.href = icon p.description = str(point) # ODLCs. oldc_folder = kml_folder.newfolder(name='ODLCs') for odlc in mission.odlcs.select_related().all(): name = 'ODLC %d' % odlc.pk gps = (odlc.location.longitude, odlc.location.latitude) p = oldc_folder.newpoint(name=name, coords=[gps]) p.iconstyle.icon.href = KML_ODLC_ICON p.description = name # Waypoints waypoints_folder = kml_folder.newfolder(name='Waypoints') linestring = waypoints_folder.newlinestring(name='Waypoints') waypoints = [] for i, waypoint in enumerate(mission.mission_waypoints.order_by('order')): coord = (waypoint.longitude, waypoint.latitude, units.feet_to_meters(waypoint.altitude_msl)) waypoints.append(coord) # Add waypoint marker p = waypoints_folder.newpoint(name='Waypoint %d' % (i + 1), coords=[coord]) p.iconstyle.icon.href = KML_WAYPOINT_ICON p.description = str(waypoint) p.altitudemode = AltitudeMode.absolute p.extrude = 1 linestring.coords = waypoints linestring.altitudemode = AltitudeMode.absolute linestring.extrude = 1 linestring.style.linestyle.color = Color.green linestring.style.polystyle.color = Color.changealphaint(100, Color.green) # Search Area search_area = [] for point in mission.search_grid_points.order_by('order'): coord = (point.longitude, point.latitude, units.feet_to_meters(point.altitude_msl)) search_area.append(coord) if search_area: search_area.append(search_area[0]) pol = kml_folder.newpolygon(name='Search Area') pol.outerboundaryis = search_area pol.style.linestyle.color = Color.blue pol.style.linestyle.width = 2 pol.style.polystyle.color = Color.changealphaint(50, Color.blue) # Map Area map_x, map_y = wgs_to_web_mercator.transform( mission.map_center_pos.longitude, mission.map_center_pos.latitude) map_height = units.feet_to_meters(mission.map_height_ft) map_width = (map_height * 16) / 9 map_points = [ (map_x - map_width / 2, map_y - map_height / 2), (map_x + map_width / 2, map_y - map_height / 2), (map_x + map_width / 2, map_y + map_height / 2), (map_x - map_width / 2, map_y + map_height / 2), (map_x - map_width / 2, map_y - map_height / 2), ] map_points = [ wgs_to_web_mercator.transform( px, py, direction=pyproj.enums.TransformDirection.INVERSE) for (px, py) in map_points ] map_points = [(x, y, 0) for (x, y) in map_points] map_pol = kml_folder.newpolygon(name='Map') map_pol.outerboundaryis = map_points map_pol.style.linestyle.color = Color.green map_pol.style.linestyle.width = 2 map_pol.style.polystyle.color = Color.changealphaint(50, Color.green) # Stationary Obstacles. stationary_obstacles_folder = kml_folder.newfolder( name='Stationary Obstacles') for obst in mission.stationary_obstacles.all(): cx, cy = wgs_to_utm.transform(obst.longitude, obst.latitude) rm = units.feet_to_meters(obst.cylinder_radius) hm = units.feet_to_meters(obst.cylinder_height) obst_points = [] for angle in np.linspace(0, 2 * math.pi, num=KML_OBST_NUM_POINTS): px = cx + rm * math.cos(angle) py = cy + rm * math.sin(angle) lon, lat = wgs_to_utm.transform( px, py, direction=pyproj.enums.TransformDirection.INVERSE) obst_points.append((lon, lat, hm)) pol = stationary_obstacles_folder.newpolygon(name='Obstacle %d' % obst.pk) pol.outerboundaryis = obst_points pol.altitudemode = AltitudeMode.absolute pol.extrude = 1 pol.style.linestyle.color = Color.yellow pol.style.linestyle.width = 2 pol.style.polystyle.color = Color.changealphaint(50, Color.yellow) return kml_folder
def mission_kml(mission, kml, kml_doc): """ Appends kml nodes describing the mission. Args: mission: The mission to add to the KML. kml: A simpleKML Container to which the mission data will be added kml_doc: The simpleKML Document to which schemas will be added Returns: The KML folder for the mission data. """ mission_name = 'Mission {}'.format(mission.pk) kml_folder = kml.newfolder(name=mission_name) # Flight boundaries. fly_zone_folder = kml_folder.newfolder(name='Fly Zones') for flyzone in mission.fly_zones.all(): fly_zone_kml(flyzone, fly_zone_folder) # Static points. locations = [ ('Home', mission.home_pos, KML_HOME_ICON), ('Emergent LKP', mission.emergent_last_known_pos, KML_ODLC_ICON), ('Off Axis', mission.off_axis_odlc_pos, KML_ODLC_ICON), ('Air Drop', mission.air_drop_pos, KML_DROP_ICON), ] for key, point, icon in locations: gps = (point.longitude, point.latitude) p = kml_folder.newpoint(name=key, coords=[gps]) p.iconstyle.icon.href = icon p.description = str(point) # ODLCs. oldc_folder = kml_folder.newfolder(name='ODLCs') for odlc in mission.odlcs.all(): name = 'ODLC %d' % odlc.pk gps = (odlc.location.longitude, odlc.location.latitude) p = oldc_folder.newpoint(name=name, coords=[gps]) p.iconstyle.icon.href = KML_ODLC_ICON p.description = name # Waypoints waypoints_folder = kml_folder.newfolder(name='Waypoints') linestring = waypoints_folder.newlinestring(name='Waypoints') waypoints = [] for i, waypoint in enumerate(mission.mission_waypoints.order_by('order')): gps = waypoint.position.gps_position coord = (gps.longitude, gps.latitude, units.feet_to_meters(waypoint.position.altitude_msl)) waypoints.append(coord) # Add waypoint marker p = waypoints_folder.newpoint(name='Waypoint %d' % (i + 1), coords=[coord]) p.iconstyle.icon.href = KML_WAYPOINT_ICON p.description = str(waypoint) p.altitudemode = AltitudeMode.absolute p.extrude = 1 linestring.coords = waypoints linestring.altitudemode = AltitudeMode.absolute linestring.extrude = 1 linestring.style.linestyle.color = Color.green linestring.style.polystyle.color = Color.changealphaint(100, Color.green) # Search Area search_area = [] for point in mission.search_grid_points.order_by('order'): gps = point.position.gps_position coord = (gps.longitude, gps.latitude, units.feet_to_meters(point.position.altitude_msl)) search_area.append(coord) if search_area: search_area.append(search_area[0]) pol = kml_folder.newpolygon(name='Search Area') pol.outerboundaryis = search_area pol.style.linestyle.color = Color.blue pol.style.linestyle.width = 2 pol.style.polystyle.color = Color.changealphaint(50, Color.blue) # Stationary Obstacles. stationary_obstacles_folder = kml_folder.newfolder( name='Stationary Obstacles') for obst in mission.stationary_obstacles.all(): gpos = obst.gps_position zone, north = distance.utm_zone(gpos.latitude, gpos.longitude) proj = distance.proj_utm(zone, north) cx, cy = proj(gpos.longitude, gpos.latitude) rm = units.feet_to_meters(obst.cylinder_radius) hm = units.feet_to_meters(obst.cylinder_height) obst_points = [] for angle in np.linspace(0, 2 * math.pi, num=KML_OBST_NUM_POINTS): px = cx + rm * math.cos(angle) py = cy + rm * math.sin(angle) lon, lat = proj(px, py, inverse=True) obst_points.append((lon, lat, hm)) pol = stationary_obstacles_folder.newpolygon(name='Obstacle %d' % obst.pk) pol.outerboundaryis = obst_points pol.altitudemode = AltitudeMode.absolute pol.extrude = 1 pol.style.linestyle.color = Color.yellow pol.style.linestyle.width = 2 pol.style.polystyle.color = Color.changealphaint(50, Color.yellow) return kml_folder