def add_link(self, sat1, sat2, start_time, end_time, color=[255, 255, 0, 255], width=1.0, id_name=None, description=None): start_time = Time(start_time, format="isot") end_time = Time(end_time, format="isot") pckt = Packet(id="s" + str(self.j), name=id_name, description=description, availability=TimeInterval(start=start_time.value, end=end_time.value), polyline=Polyline( positions=PositionList(references=[ str(sat1) + "#position", str(sat2) + "#position" ]), material=Material(solidColor=SolidColorMaterial( color=Color(rgba=color))), width=width, )) self.packets.append(pckt) self.j += 1
def test_material_image(): expected_result = """{ "image": { "image": "https://site.com/image.png", "repeat": [ 2, 2 ], "color": { "rgba": [ 200, 100, 30, 255 ] }, "transparent": false } }""" mat = Material(image=ImageMaterial( image=Uri(uri="https://site.com/image.png"), repeat=[2, 2], color=Color.from_list([200, 100, 30]), )) assert repr(mat) == expected_result pol_mat = PolylineMaterial(image=ImageMaterial( image=Uri(uri="https://site.com/image.png"), repeat=[2, 2], color=Color.from_list([200, 100, 30]), )) assert repr(pol_mat) == expected_result
def write_rx_czml(): height = 50 receiver_point_packets = [] lob_packets = [] top = Preamble(name="Receivers") rx_properties = { "verticalOrigin": "BOTTOM", "scale": 0.75, "heightReference":"CLAMP_TO_GROUND", "height": 48, "width": 48, } for index, x in enumerate(receivers): if x.isActive and ms.receiving: lob_start_lat = x.latitude lob_start_lon = x.longitude lob_stop_lat, lob_stop_lon = v.direct(lob_start_lat, lob_start_lon, x.doa, d) lob_packets.append(Packet(id=f"LOB-{x.station_id}-{index}", polyline=Polyline( material= Material( polylineOutline = PolylineOutlineMaterial( color= Color(rgba=[255, 140, 0, 255]), outlineColor= Color(rgba=[0, 0, 0, 255]), outlineWidth= 2 )), clampToGround=True, width=5, positions=Position(cartographicDegrees=[lob_start_lon, lob_start_lat, height, lob_stop_lon, lob_stop_lat, height]) ))) else: lob_packets = [] if x.isMobile == True: rx_icon = {"image":{"uri":"/static/flipped_car.svg"}} # if x.heading > 0 or x.heading < 180: # rx_icon = {"image":{"uri":"/static/flipped_car.svg"}, "rotation":math.radians(360 - x.heading + 90)} # elif x.heading < 0 or x.heading > 180: # rx_icon = {"image":{"uri":"/static/car.svg"}, "rotation":math.radians(360 - x.heading - 90)} else: rx_icon = {"image":{"uri":"/static/tower.svg"}} receiver_point_packets.append(Packet(id=f"{x.station_id}-{index}", billboard={**rx_properties, **rx_icon}, position={"cartographicDegrees": [ x.longitude, x.latitude, 15 ]})) output = Document([top] + receiver_point_packets + lob_packets) return output
def packet_from_polygon(feat, id_=None): name = feat.get( "name", "polygon_{}".format(id_) if id_ is not None else "polygon_0") description = feat.get("description", name) color = get_color(feat.get("color", 0xff0000)) polygon = feat.get_shape(WGS84_CRS) return Packet( id=id_, name=name, description=description, polygon=Polygon( positions=PositionList(cartographicDegrees=list( flatten_line(fill_height(polygon.exterior.coords)))), material=Material(solidColor=SolidColorMaterial(color=color)), ), )
def test_material_solid_color(): expected_result = """{ "solidColor": { "color": { "rgba": [ 200, 100, 30, 255 ] } } }""" mat = Material(solidColor=SolidColorMaterial.from_list([200, 100, 30])) assert repr(mat) == expected_result pol_mat = PolylineMaterial(solidColor=SolidColorMaterial.from_list([200, 100, 30])) assert repr(pol_mat) == expected_result
def test_make_czml_png_rectangle_file(image): wsen = [20, 40, 21, 41] rectangle_packet = Packet( id="id_00", rectangle=Rectangle( coordinates=RectangleCoordinates(wsenDegrees=wsen), fill=True, material=Material(image=ImageMaterial( transparent=True, repeat=None, image="data:image/png;base64," + image, ), ), ), ) with tempfile.NamedTemporaryFile(mode="w", suffix=".czml") as out_file: out_file.write(str(Document([Preamble(), rectangle_packet]))) exists = os.path.isfile(out_file.name) # TODO: Should we be testing something else? assert exists
def test_packet_rectangles(image): wsen = [20, 40, 21, 41] expected_result = """{{ "id": "id_00", "rectangle": {{ "coordinates": {{ "wsenDegrees": [ {}, {}, {}, {} ] }}, "fill": true, "material": {{ "image": {{ "image": "data:image/png;base64,{}", "transparent": true }} }} }} }}""".format(*wsen, image) rectangle_packet = Packet( id="id_00", rectangle=Rectangle( coordinates=RectangleCoordinates(wsenDegrees=wsen), fill=True, material=Material(image=ImageMaterial( transparent=True, repeat=None, image="data:image/png;base64," + image, ), ), ), ) assert repr(rectangle_packet) == expected_result
def add_trajectory( self, positions, epochs, groundtrack_show=False, groundtrack_lead_time=None, groundtrack_trail_time=None, groundtrack_width=None, groundtrack_color=None, id_name=None, id_description=None, path_width=None, path_show=None, path_color=None, label_fill_color=None, label_outline_color=None, label_font=None, label_text=None, label_show=None, ): """ Adds trajectory. Parameters ---------- positions: ~astropy.coordinates.CartesianRepresentation Trajectory to plot. epochs: ~astropy.time.Time Epochs for positions. groundtrack_show: bool If set to true, the groundtrack is displayed. groundtrack_lead_time: float The time the animation is ahead of the real-time groundtrack groundtrack_trail_time: float The time the animation is behind the real-time groundtrack groundtrack_width: int Groundtrack width groundtrack_color: list (int) Rgba groundtrack color. By default, it is set to the path color id_name: str Set orbit name id_description: str Set orbit description path_width: int Path width path_show: bool Indicates whether the path is visible path_color: list (int) Rgba path color label_fill_color: list (int) Fill Color in rgba format label_outline_color: list (int) Outline Color in rgba format label_font: str Set label font style and size (CSS syntax) label_text: str Set label text label_show: bool Indicates whether the label is visible """ positions = (positions.represent_as(CartesianRepresentation).get_xyz( 1).to_value(u.m)) epochs = Time(epochs, format="isot") if len(epochs) != len(positions): raise ValueError("Number of Points and Epochs must be equal.") epochs = np.fromiter( map(lambda epoch: (epoch - epochs[0]).to_value(u.s), epochs), dtype=float, ) positions = np.around( np.concatenate([epochs[..., None], positions], axis=1).ravel(), 1).tolist() self.trajectories.append([positions, None, label_text, path_color]) start_epoch = Time(self.start_epoch, format="isot") pckt = Packet( id=self.i, name=id_name, description=id_description, availability=TimeInterval(start=self.start_epoch, end=self.end_epoch), position=Position( interpolationDegree=5, interpolationAlgorithm=InterpolationAlgorithms.LAGRANGE, referenceFrame=ReferenceFrames.INERTIAL, cartesian=positions, # Use explicit UTC timezone, rather than the default, which is a local timezone. epoch=start_epoch.datetime.replace(tzinfo=timezone.utc), ), path=Path( show=path_show, width=path_width, material=Material(solidColor=SolidColorMaterial( color=Color.from_list(path_color))) if path_color is not None else Material(solidColor=SolidColorMaterial( color=Color.from_list([255, 255, 0]))), resolution=120, ), label=Label( text=label_text, font=label_font if label_font is not None else "11pt Lucida Console", show=label_show, fillColor=Color(rgba=label_fill_color) if label_fill_color is not None else Color(rgba=[255, 255, 0, 255]), outlineColor=Color(rgba=label_outline_color) if label_outline_color is not None else Color( rgba=[255, 255, 0, 255]), ), billboard=Billboard(image=PIC_SATELLITE, show=True), ) self.packets.append(pckt) if groundtrack_show: raise NotImplementedError( "Ground tracking for trajectory not implemented yet") self.i += 1
def add_orbit( self, orbit, rtol=1e-10, N=None, groundtrack_show=False, groundtrack_lead_time=None, groundtrack_trail_time=None, groundtrack_width=None, groundtrack_color=None, id_name=None, id_description=None, path_width=None, path_show=None, path_color=None, label_fill_color=None, label_outline_color=None, label_font=None, label_text=None, label_show=None, ): """ Adds an orbit Parameters ---------- orbit: poliastro.twobody.orbit.Orbit Orbit to be added rtol: float Maximum relative error permitted N: int Number of sample points groundtrack_show: bool If set to true, the groundtrack is displayed. groundtrack_lead_time: float The time the animation is ahead of the real-time groundtrack groundtrack_trail_time: float The time the animation is behind the real-time groundtrack groundtrack_width: int Groundtrack width groundtrack_color: list (int) Rgba groundtrack color. By default, it is set to the path color id_name: str Set orbit name id_description: str Set orbit description path_width: int Path width path_show: bool Indicates whether the path is visible path_color: list (int) Rgba path color label_fill_color: list (int) Fill Color in rgba format label_outline_color: list (int) Outline Color in rgba format label_font: str Set label font style and size (CSS syntax) label_text: str Set label text label_show: bool Indicates whether the label is visible """ if N is None: N = self.N if orbit.epoch < self.start_epoch: orbit = orbit.propagate(self.start_epoch - orbit.epoch) elif orbit.epoch > self.end_epoch: raise ValueError( "The orbit's epoch cannot exceed the constructor's ending epoch" ) if rtol <= 0 or rtol >= 1: raise ValueError( "The relative tolerance must be a value in the range (0, 1)") self.orbits.append([orbit, N, orbit.epoch]) cartesian_cords = self._init_orbit_packet_cords_(self.i, rtol=rtol) start_epoch = Time(min(self.orbits[self.i][2], self.start_epoch), format="isot") pckt = Packet( id=self.i, name=id_name, description=id_description, availability=TimeInterval(start=self.start_epoch, end=self.end_epoch), position=Position( interpolationDegree=5, interpolationAlgorithm=InterpolationAlgorithms.LAGRANGE, referenceFrame=ReferenceFrames.INERTIAL, cartesian=cartesian_cords, # Use explicit UTC timezone, rather than the default, which is a local timezone. epoch=start_epoch.datetime.replace(tzinfo=timezone.utc), ), path=Path( show=path_show, width=path_width, material=Material(solidColor=SolidColorMaterial( color=Color.from_list(path_color))) if path_color is not None else Material(solidColor=SolidColorMaterial( color=Color.from_list([255, 255, 0]))), resolution=120, ), label=Label( text=label_text, font=label_font if label_font is not None else "11pt Lucida Console", show=label_show, fillColor=Color(rgba=label_fill_color) if label_fill_color is not None else Color(rgba=[255, 255, 0, 255]), outlineColor=Color(rgba=label_outline_color) if label_outline_color is not None else Color( rgba=[255, 255, 0, 255]), ), billboard=Billboard(image=PIC_SATELLITE, show=True), ) self.packets.append(pckt) if groundtrack_show: groundtrack_color = path_color groundtrack_cords = self._init_groundtrack_packet_cords_(self.i, rtol=rtol) pckt = Packet( id="groundtrack" + str(self.i), availability=TimeInterval(start=self.start_epoch, end=self.end_epoch), position=Position( interpolationDegree=5, interpolationAlgorithm=InterpolationAlgorithms.LAGRANGE, referenceFrame=ReferenceFrames.INERTIAL, cartesian=groundtrack_cords, # Use explicit UTC timezone, rather than the default, which is a local timezone. epoch=start_epoch.datetime.replace(tzinfo=timezone.utc), ), path=Path( show=True, material=Material(solidColor=SolidColorMaterial( color=Color(rgba=groundtrack_color))) if groundtrack_color is not None else Material( solidColor=SolidColorMaterial(color=Color( rgba=[255, 255, 0, 255]))), resolution=60, width=groundtrack_width, leadTime=groundtrack_lead_time if groundtrack_lead_time else 100, trailTime=groundtrack_trail_time if groundtrack_trail_time else 100, ), ) self.packets.append(pckt) self.i += 1
def test_packet_polygon(): expected_result = """{ "id": "id_00", "polygon": { "positions": { "cartographicDegrees": [ -115.0, 37.0, 0, -115.0, 32.0, 0, -107.0, 33.0, 0, -102.0, 31.0, 0, -102.0, 35.0, 0 ] }, "granularity": 1.0, "material": { "solidColor": { "color": { "rgba": [ 255, 0, 0, 255 ] } } } } }""" packet = Packet( id="id_00", polygon=Polygon( positions=PositionList( cartographicDegrees=[ -115.0, 37.0, 0, -115.0, 32.0, 0, -107.0, 33.0, 0, -102.0, 31.0, 0, -102.0, 35.0, 0, ] ), granularity=1.0, material=Material(solidColor=SolidColorMaterial.from_list([255, 0, 0])), ), ) assert repr(packet) == expected_result
def add_orbit( self, orbit, rtol=1e-10, N=None, id_name=None, id_description=None, path_width=None, path_show=None, path_color=None, label_fill_color=None, label_outline_color=None, label_font=None, label_text=None, label_show=None, ): """ Adds an orbit Parameters ---------- orbit: poliastro.Orbit Orbit to be added rtol: float Maximum relative error permitted N: int Number of sample points Id parameters: ------------- id_name: str Set orbit name id_description: str Set orbit description Path parameters --------------- path_width: int Path width path_show: bool Indicates whether the path is visible path_color: list (int) Rgba path color Label parameters ---------- label_fill_color: list (int) Fill Color in rgba format label_outline_color: list (int) Outline Color in rgba format label_font: str Set label font style and size (CSS syntax) label_text: str Set label text label_show: bool Indicates whether the label is visible """ if N is None: N = self.N if orbit.epoch < Time(self.start_epoch): orbit = orbit.propagate(self.start_epoch - orbit.epoch) elif orbit.epoch > Time(self.end_epoch): raise ValueError( "The orbit's epoch cannot exceed the constructor's ending epoch" ) if rtol <= 0 or rtol >= 1: raise ValueError( "The relative tolerance must be a value in the range (0, 1)") self.orbits.append([orbit, N, orbit.epoch]) cartesian_cords = self._init_orbit_packet_cords_(self.i, rtol=rtol) start_epoch = Time(min(self.orbits[self.i][2], self.start_epoch), format="isot") pckt = Packet( id=self.i, name=id_name, description=id_description, availability=TimeInterval(start=self.start_epoch.datetime, end=self.end_epoch.datetime), position=Position( interpolationDegree=5, interpolationAlgorithm=InterpolationAlgorithms.LAGRANGE, referenceFrame=ReferenceFrames.INERTIAL, cartesian=cartesian_cords, epoch=start_epoch.value, ), path=Path( show=path_show, width=path_width, material=Material(solidColor=SolidColorMaterial(color=Color( rgba=path_color))) if path_color is not None else Material( solidColor=SolidColorMaterial(color=Color( rgba=[255, 255, 0, 255]))), resolution=120, ), label=Label( text=label_text, font=label_font if label_font is not None else "11pt Lucida Console", show=label_show, fillColor=Color(rgba=label_fill_color) if label_fill_color is not None else Color(rgba=[255, 255, 0, 255]), outlineColor=Color(rgba=label_outline_color) if label_outline_color is not None else Color( rgba=[255, 255, 0, 255]), ), billboard=Billboard(image=PIC_SATELLITE, show=True), ) self.packets.append(pckt) self.i += 1
label=Label( horizontalOrigin=HorizontalOrigins.LEFT, outlineWidth=2, show=True, font="11pt Lucida Console", style=LabelStyles.FILL_AND_OUTLINE, text="Geoeye 1", verticalOrigin=VerticalOrigins.CENTER, fillColor=Color.from_list([0, 255, 0]), outlineColor=Color.from_list([0, 0, 0]), ), path=Path( show=Sequence([IntervalValue(start=start, end=end, value=True)]), width=1, resolution=120, material=Material(solidColor=SolidColorMaterial.from_list([0, 255, 0])), ), position=Position( interpolationAlgorithm=InterpolationAlgorithms.LAGRANGE, interpolationDegree=5, referenceFrame=ReferenceFrames.INERTIAL, epoch=start, cartesian=[ 0, 4650397.56551457, -3390535.52275848, -4087729.48877329, 300, 3169722.12564676, -2787480.80604407, -5661647.74541255,