flopp / py-staticmaps

A python module to create static map images with markers, geodesic lines, etc.
MIT License
128 stars 17 forks source link

ScaleBar? #35

Open petered opened 6 months ago

petered commented 6 months ago

First off - thank you for making this very useful tool.

It would be great to have some way to add a scalebar.

I recognise it gets a little tricky over large-projections where scale is not uniform - but most maps are local.

Here's my attempt so far:

    def render(self, width: int, height: int, add_scalebar: bool = True) -> BGRImageArray:
        image = self.context.render_pillow(width, height)
        bgr_image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
        if add_scalebar:
            center, zoom = self.context.determine_center_zoom(width, height)
            trans = Transformer(width, height, zoom, center, tile_size=256)  # TODO: Get actual tile size from context
            lower_left=trans.pixel2ll(0, 0)
            lower_right=trans.pixel2ll(width-1, 0)
            upper_left=trans.pixel2ll(0, height-1)
            map_width_m = inter_latlong_distance_m((lower_left.lat().degrees, lower_left.lng().degrees), (lower_right.lat().degrees, lower_right.lng().degrees))
            map_height_m = inter_latlong_distance_m((lower_left.lat().degrees, lower_left.lng().degrees), (upper_left.lat().degrees, upper_left.lng().degrees))
            bgr_image = ImageBuilder(bgr_image).draw_corner_text(text='Scale: {:.2f} x {:.2f} km'.format(map_width_m/1000, map_height_m/1000), colour=BGRColors.WHITE, shadow_color=BGRColors.BLACK).get_image()
        return bgr_image

Which puts a little text-box in the corner:

image