def logical_extents(self) -> CanvasBbox: extent = self._layout.get_extents()[1] x = CanvasUnit.from_pt(pangocffi.units_to_double(extent.x)) y = CanvasUnit.from_pt(pangocffi.units_to_double(extent.y)) x += self._position.x y += self._position.y width = CanvasUnit.from_pt(pangocffi.units_to_double(extent.width)) height = CanvasUnit.from_pt(pangocffi.units_to_double(extent.height)) return CanvasBbox(CanvasCoordinate(x, y), width, height)
def test_conversion(self): wgs84_crs = pyproj.CRS.from_epsg(4326) british_crs = pyproj.CRS.from_epsg(27700) coordinate_to_project = GeoCoordinate(55.862777, -4.260919, wgs84_crs) expected_canvas_coordinates = CanvasCoordinate( CanvasUnit.from_cm(1 + 6), CanvasUnit.from_cm(1 + 4)).pt origin_for_geo = GeoCoordinate(258000, 666000, british_crs) origin_for_canvas = CanvasCoordinate(CanvasUnit.from_cm(1), CanvasUnit.from_cm(1)) # 100 meters for every centimeter geo_to_canvas_scale = geo_canvas_ops.GeoCanvasScale( 100, CanvasUnit.from_cm(1)) transformation_func = geo_canvas_ops.build_transformer( crs=british_crs, data_crs=wgs84_crs, scale=geo_to_canvas_scale, origin_for_geo=origin_for_geo, origin_for_canvas=origin_for_canvas) self.assert_coordinates_are_close( transformation_func(*coordinate_to_project.tuple), expected_canvas_coordinates) # Repeat the same test, but this time without data_crs: transformation_func = geo_canvas_ops.build_transformer( crs=british_crs, scale=geo_to_canvas_scale, origin_for_geo=origin_for_geo, origin_for_canvas=origin_for_canvas) coordinate_to_project = GeoCoordinate(258600, 665600, british_crs) self.assert_coordinates_are_close( transformation_func(*coordinate_to_project.tuple), expected_canvas_coordinates)
def test_setters_and_getters(self): # Create a canvas for the sake of instantiating a layout object. We do # this because that is how Pango actually resolves the font dimensions. path = Path(__file__).parent.joinpath( 'output/layout_setters_and_getters.svg') canvas_builder = CanvasBuilder() canvas_builder.set_path(path) canvas_builder.set_size(Cu.from_pt(100), Cu.from_pt(100)) canvas = canvas_builder.build() layout = Layout(canvas) layout.set_text('Hello world') layout.set_markup('<span weight="bold">Hello world!</span>') assert layout.width is None assert layout.height is None layout.width = Cu.from_pt(100) layout.height = Cu.from_pt(50) assert layout.width.pt == 100 assert layout.height.pt == 50 layout.reset_width() layout.reset_height() assert layout.width is None assert layout.height is None assert layout.position.x.pt == 0 assert layout.position.y.pt == 0 layout.position = CanvasCoordinate(Cu.from_pt(10), Cu.from_pt(5)) assert layout.position.x.pt == 10 assert layout.position.y.pt == 5 assert layout.color == (0, 0, 0, 1) layout.color = (0, 1, 0, 0.5) assert layout.color == (0, 1, 0, 0.5) assert layout.alignment == Alignment.LEFT layout.alignment = Alignment.RIGHT assert layout.alignment == Alignment.RIGHT extents = layout.logical_extents assert extents.pos.x.pt == 10 assert extents.pos.y.pt == 5 assert extents.width.pt > 1 assert extents.height.pt > 1
def draw_azimuthal( self, canvas: Canvas, crs: CRS, mask_proj: Polygon, world_map_wgs84: MultiPolygon, flight_paths_wgs84: MultiLineString ): origin_for_geo = GeoCoordinate(0, 0, crs) origin_x = Cu.from_px(self.margin + self.azimuthal_width / 2) origin_y = Cu.from_px(self.margin + self.azimuthal_height / 2) origin_for_canvas = CanvasCoordinate(origin_x, origin_y) # Fit the projected radius as the width of the canvas geo_to_canvas_scale = geo_canvas_ops.GeoCanvasScale( crs.ellipsoid.semi_major_metre, Cu.from_px(self.azimuthal_width / 2) ) # Convert the projected mask to the canvas. proj_to_canvas = geo_canvas_ops.build_transformer( crs=crs, data_crs=crs, scale=geo_to_canvas_scale, origin_for_geo=origin_for_geo, origin_for_canvas=origin_for_canvas ) mask_canvas = ops.transform(proj_to_canvas, mask_proj) # Convert the world map, from wgs84 to proj to canvas wgs84_crs = CRS.from_epsg(4326) wgs84_to_canvas = geo_canvas_ops.build_transformer( crs=crs, data_crs=wgs84_crs, scale=geo_to_canvas_scale, origin_for_geo=origin_for_geo, origin_for_canvas=origin_for_canvas ) world_map_canvas = transform_interpolated_euclidean( wgs84_to_canvas, world_map_wgs84 ) flight_paths_canvas = transform_interpolated_euclidean( wgs84_to_canvas, flight_paths_wgs84 ) # Render the polygons polygon_drawer = PolygonDrawer() polygon_drawer.fill_color = self.sea_color polygon_drawer.geoms = [mask_canvas] polygon_drawer.draw(canvas) polygon_drawer = PolygonDrawer() polygon_drawer.fill_color = self.land_color polygon_drawer.geoms = [world_map_canvas] polygon_drawer.draw(canvas) polygon_drawer = LineDrawer() polygon_drawer.stroke_color = self.line_color polygon_drawer.geoms = [flight_paths_canvas] polygon_drawer.draw(canvas)
def draw_wgs84( self, canvas: Canvas, mask_wgs84: MultiPolygon, world_map_wgs84: MultiPolygon, flight_paths_wgs84: MultiLineString ): wgs84_crs = CRS.from_epsg(4326) origin_for_geo = GeoCoordinate( 0, 0, wgs84_crs ) origin_for_canvas = CanvasCoordinate( Cu.from_px(self.margin * 2 + self.azimuthal_width + self.wgs84_width / 2), Cu.from_px(self.margin + self.wgs84_height / 2) ) # 1 pixel for every degree geo_to_canvas_scale = geo_canvas_ops.GeoCanvasScale( 1, Cu.from_px(1) ) # Todo: These transformations should be handled by build_transformer. mask_wgs84 = ops.transform(lambda x, y: (y, x), mask_wgs84) world_map_wgs84 = ops.transform(lambda x, y: (y, x), world_map_wgs84) flight_paths_wgs84 = ops.transform( lambda x, y: (y, x), flight_paths_wgs84 ) # Generate a polygon that represents the full range. domain_wgs84 = Polygon( [(-180, -90), (180, -90), (180, 90), (-180, 90)] ) wgs84_to_canvas = geo_canvas_ops.build_transformer( crs=wgs84_crs, data_crs=wgs84_crs, scale=geo_to_canvas_scale, origin_for_geo=origin_for_geo, origin_for_canvas=origin_for_canvas ) mask_canvas = ops.transform(wgs84_to_canvas, mask_wgs84) world_map_canvas = ops.transform(wgs84_to_canvas, world_map_wgs84) flight_paths_canvas = ops.transform( wgs84_to_canvas, flight_paths_wgs84 ) domain_canvas = ops.transform(wgs84_to_canvas, domain_wgs84) polygon_drawer = PolygonDrawer() polygon_drawer.fill_color = (0, 0, 0) polygon_drawer.geoms = [domain_canvas] polygon_drawer.draw(canvas) polygon_drawer = PolygonDrawer() polygon_drawer.fill_color = self.sea_color polygon_drawer.geoms = [mask_canvas] polygon_drawer.draw(canvas) polygon_drawer = PolygonDrawer() polygon_drawer.fill_color = self.land_color polygon_drawer.geoms = [world_map_canvas] polygon_drawer.draw(canvas) polygon_drawer = LineDrawer() polygon_drawer.stroke_color = self.line_color polygon_drawer.geoms = [flight_paths_canvas] polygon_drawer.draw(canvas)