def test_outline_material_colors(): expected_result = """{ "color": { "rgba": [ 200, 100, 30, 255 ] }, "outlineColor": { "rgba": [ 100, 200, 0, 255 ] }, "outlineWidth": 3 }""" omat = PolylineOutlineMaterial( color=Color(rgba=[200, 100, 30, 255]), outlineColor=Color(rgba=[100, 200, 0, 255]), outlineWidth=3, ) assert repr(omat) == expected_result
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 test_material_stripe(): expected_result = """{ "orientation": "HORIZONTAL", "evenColor": { "rgba": [ 0, 0, 0, 255 ] }, "oddColor": { "rgba": [ 255, 255, 255, 255 ] }, "offset": 0.3, "repeat": 4 }""" pol_mat = StripeMaterial( evenColor=Color.from_list([0, 0, 0]), oddColor=Color.from_list([255, 255, 255]), offset=0.3, repeat=4, ) assert repr(pol_mat) == expected_result
def test_dashmaterial_colors(): expected_result = """{ "color": { "rgba": [ 200, 100, 30, 255 ] }, "gapColor": { "rgba": [ 100, 200, 0, 255 ] }, "dashLength": 16, "dashPattern": 255 }""" dashmat = PolylineDashMaterial( color=Color(rgba=[200, 100, 30, 255]), gapColor=Color(rgba=[100, 200, 0, 255]), dashLength=16, dashPattern=255, ) assert repr(dashmat) == expected_result
def test_material_checkerboard(): expected_result = """{ "evenColor": { "rgba": [ 0, 0, 0, 255 ] }, "oddColor": { "rgba": [ 255, 255, 255, 255 ] }, "repeat": 4 }""" pol_mat = CheckerboardMaterial( evenColor=Color.from_list([0, 0, 0]), oddColor=Color.from_list([255, 255, 255]), repeat=4, ) assert repr(pol_mat) == expected_result
def test_color_isvalid_false(): assert Color.is_valid([256, 204, 0, 55]) is False assert Color.is_valid([-204, 0, 55]) is False assert Color.is_valid([249.1, 204.3, 55.4]) is False assert Color.is_valid([255, 204]) is False assert Color.is_valid([255, 232, 300]) is False assert Color.is_valid(0xFF3223324) is False assert Color.is_valid(-3) is False assert Color.is_valid("totally valid color") is False assert Color.is_valid("#FF322332432") is False
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 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_grid(): expected_result = """{ "color": { "rgba": [ 20, 20, 30, 255 ] }, "cellAlpha": 1.0, "lineCount": [ 16, 16 ], "lineThickness": [ 2.0, 2.0 ], "lineOffset": [ 0.3, 0.4 ] }""" pol_mat = GridMaterial( color=Color.from_list([20, 20, 30]), cellAlpha=1.0, lineCount=[16, 16], lineThickness=[2.0, 2.0], lineOffset=[0.3, 0.4], ) assert repr(pol_mat) == expected_result
def test_get_color_rgba(): expected_color = Color(rgba=RgbaValue(values=[255, 204, 0, 255])) assert get_color("#ffcc00") == expected_color assert get_color(0xFFCC00) == expected_color assert get_color("#ffcc00ff") == expected_color assert get_color(0xFFCC00FF) == expected_color assert get_color([255, 204, 0]) == expected_color assert get_color([255, 204, 0, 255]) == expected_color
def test_color_isvalid(): assert Color.is_valid([255, 204, 0, 55]) assert Color.is_valid([255, 204, 55]) assert Color.is_valid(0xFF3223) assert Color.is_valid(32) assert Color.is_valid(0xFF322332) assert Color.is_valid("#FF3223") assert Color.is_valid("#FF322332")
def test_color_rgba_from_tuple(): expected_result = """{ "rgba": [ 100, 200, 255, 255 ] }""" tc = Color.from_tuple((100, 200, 255)) assert repr(tc) == expected_result
def test_color_rgbaf_from_tuple(): expected_result = """{ "rgbaf": [ 0.127568, 0.566949, 0.550556, 1.0 ] }""" tc = Color.from_tuple((0.127568, 0.566949, 0.550556, 1.0)) assert repr(tc) == expected_result
def test_arrowmaterial_color(): expected_result = """{ "color": { "rgba": [ 200, 100, 30, 255 ] } }""" pamat = PolylineArrowMaterial(color=Color(rgba=[200, 100, 30, 255])) assert repr(pamat) == expected_result
def test_packet_label(): expected_result = """{ "id": "0", "label": { "show": true, "font": "20px sans-serif", "style": "FILL", "fillColor": { "rgbaf": [ 0.2, 0.3, 0.4, 1.0 ] }, "outlineColor": { "rgba": [ 0, 233, 255, 2 ] }, "outlineWidth": 2.0 } }""" packet = Packet( id="0", label=Label( font="20px sans-serif", fillColor=Color.from_list([0.2, 0.3, 0.4]), outlineColor=Color.from_list([0, 233, 255, 2]), outlineWidth=2.0, ), ) assert repr(packet) == expected_result
def test_packet_point(): expected_result = """{ "id": "id_00", "point": { "color": { "rgba": [ 255, 0, 0, 255 ] } } }""" packet = Packet(id="id_00", point=Point(color=Color.from_list([255, 0, 0, 255]))) assert repr(packet) == expected_result
def test_glowmaterial_color(): expected_result = """{ "color": { "rgba": [ 200, 100, 30, 255 ] }, "glowPower": 0.7, "taperPower": 0.3 }""" glowmat = PolylineGlowMaterial(color=Color(rgba=[200, 100, 30, 255]), glowPower=0.7, taperPower=0.3) assert repr(glowmat) == expected_result
def test_get_color_list_of_colors_rgba(): expected_color = Color(rgba=RgbaValue(values=[ "0000-00-00T00:00:00Z", 255, 204, 0, 255, "9999-12-31T24:00:00Z", 255, 204, 0, 255, ])) assert (get_color_list( ["0000-00-00T00:00:00Z", "9999-12-31T24:00:00Z"], [[1.0, 0.8, 0.0, 1.0], 0xFFCC00FF], ) == expected_color) assert (get_color_list(["0000-00-00T00:00:00Z", "9999-12-31T24:00:00Z"], ["#ffcc00ff", 0xFFCC00]) == expected_color)
def test_get_color_list_of_colors_rgbaf(): expected_color = Color(rgbaf=RgbafValue(values=[ "0000-00-00T00:00:00Z", 1.0, 0.8, 0.0, 1.0, "9999-12-31T24:00:00Z", 1.0, 0.8, 0.0, 1.0, ])) assert (get_color_list( ["0000-00-00T00:00:00Z", "9999-12-31T24:00:00Z"], [[1.0, 0.8, 0.0, 1.0], 0xFFCC00], rgbaf=True, ) == expected_color) assert (get_color_list( ["0000-00-00T00:00:00Z", "9999-12-31T24:00:00Z"], [[255, 204, 0], 0xFFCC00FF], rgbaf=True, ) == expected_color)
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 add_ground_station( self, pos, id_description=None, label_fill_color=None, label_font=None, label_outline_color=None, label_text=None, label_show=True, ): """ Adds a ground station Parameters ---------- pos: list [~astropy.units.Quantity] Coordinates of ground station, list of geodetic latitude and longitude [lon, lat] (0 elevation) id_description: str Set ground station description 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 (len(pos) == 2 and isinstance(pos[0], u.quantity.Quantity) and isinstance(pos[0], u.quantity.Quantity)): u0, v0 = pos if self.cust_prop[0]: a, b = ( self.cust_prop[0][0], self.cust_prop[0][2], ) # Get semi-major and semi-minor axises else: a, b = Earth.R.to_value(u.m), Earth.R_polar.to_value(u.m) f = 1 - (b / a) # Flattenning pos = list(gd2gce(a, f, u0.to_value(u.rad), v0.to_value(u.rad), 0)) else: raise TypeError( "Invalid coordinates. Coordinates must be of the form [u, v] where u, v are astropy units" ) pckt = Packet( id="GS" + str(self.gs_n), description=id_description, availability=TimeInterval(start=self.start_epoch, end=self.end_epoch), position=Position(cartesian=pos), label=Label( show=label_show, text=label_text, font=label_font if label_font is not None else "11pt Lucida Console", fillColor=Color(rgba=label_fill_color) if label_fill_color is not None else None, outlineColor=Color(rgba=label_outline_color) if label_outline_color is not None else None, ), billboard=Billboard(image=PIC_GROUNDSTATION, show=True), ) self.packets.append(pckt) self.gs_n += 1
def test_get_color_rgbaf(): expected_color = Color(rgbaf=RgbafValue(values=[1.0, 0.8, 0.0, 1.0])) # TODO: Simplify after https://github.com/poliastro/czml3/issues/36 assert get_color([1.0, 0.8, 0.0]) == expected_color assert get_color([1.0, 0.8, 0.0, 1.0]) == expected_color
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
def add_ground_station( self, pos, id_description=None, label_fill_color=None, label_font=None, label_outline_color=None, label_text=None, label_show=True, ): """ Adds a ground station Parameters ---------- orbit: poliastro.Orbit Orbit to be added pos: list [~astropy.units] coordinates of ground station [u v] ellipsoidal coordinates (0 elevation) Id parameters: ------------- id_description: str Set ground station description 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 (len(pos) == 2 and isinstance(pos[0], u.quantity.Quantity) and isinstance(pos[0], u.quantity.Quantity)): u0, v0 = pos if self.cust_prop[0]: a, b = ( self.cust_prop[0][0], self.cust_prop[0][2], ) # get semi-major and semi-minor axises else: a, b = Earth.R.to(u.m).value, Earth.R_polar.to(u.m).value pos = list( map(lambda x: x.value, ellipsoidal_to_cartesian(a, b, u0, v0))) else: raise TypeError( "Invalid coordinates. Coordinates must be of the form [u, v] where u, v are astropy units" ) pckt = Packet( id="GS" + str(self.gs_n), description=id_description, availability=TimeInterval(start=self.start_epoch, end=self.end_epoch), position=Position(cartesian=pos), label=Label( show=label_show, text=label_text, font=label_font if label_font is not None else "11pt Lucida Console", fillColor=Color(rgba=label_fill_color) if label_fill_color is not None else None, outlineColor=Color(rgba=label_outline_color) if label_outline_color is not None else None, ), billboard=Billboard(image=PIC_GROUNDSTATION, show=True), ) self.packets.append(pckt) self.gs_n += 1
def test_color_isvalid_false(): assert Color.is_valid([256, 204, 0, 55]) is False assert Color.is_valid([-204, 0, 55]) is False assert Color.is_valid([249.1, 204.3, 55.4]) is False assert Color.is_valid([255, 204]) is False assert Color.is_valid([255, 232, 300]) is False assert Color.is_valid(0xFF3223324) is False assert Color.is_valid(-3) is False assert Color.is_valid("totally valid color") is False assert Color.is_valid("#FF322332432") is False assert Color.is_valid((255, 204, 55, 255, 42)) is False assert Color.is_valid((0.127568, 0.566949, 0.550556, 1.0, 3.0)) is False
def test_color_isvalid(): assert Color.is_valid([255, 204, 0, 55]) assert Color.is_valid([255, 204, 55]) assert Color.is_valid(0xFF3223) assert Color.is_valid(32) assert Color.is_valid(0xFF322332) assert Color.is_valid("#FF3223") assert Color.is_valid("#FF322332") assert Color.is_valid((255, 204, 55)) assert Color.is_valid((255, 204, 55, 255)) assert Color.is_valid((0.127568, 0.566949, 0.550556)) assert Color.is_valid((0.127568, 0.566949, 0.550556, 1.0))
name="AGI to Sensor", parent=accesses_id, description="<h2>No accesses</h2>", ), Packet( id="AreaTarget/Pennsylvania", name="Pennsylvania", label=Label( horizontalOrigin=HorizontalOrigins.LEFT, show=True, font="11pt Lucida Console", style=LabelStyles.FILL_AND_OUTLINE, outlineWidth=2, text="Pennsylvania", verticalOrigin=VerticalOrigins.CENTER, fillColor=Color.from_list([255, 0, 0]), outlineColor=Color.from_list([0, 0, 0]), ), position=Position( cartesian=[1152255.80150063, -4694317.951340558, 4147335.9067563135] ), ), Packet( id="Facility/AGI", name="AGI", availability=TimeInterval(start=start, end=end), billboard=Billboard( horizontalOrigin=HorizontalOrigins.CENTER, image=( "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/" "9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAc"