from abc import abstractmethod from dataclasses import dataclass from typing import Optional from PIL import Image import plotly.graph_objects as go from geoguessr_bot.interfaces import Coordinate @dataclass class AbstractGuessr: """Abstract class for a guessr """ @abstractmethod def guess(self, image: Image) -> Coordinate: raise NotImplementedError def guess_from_path(self, image_path: str) -> Coordinate: image = Image.open(image_path) return self.guess(image) @staticmethod def create_map(guess_coordinate: Optional[Coordinate] = None, **kwargs) -> go.Figure: """Create an interactive map showing a coordinate """ fig = go.Figure(go.Scattermapbox( customdata=[str(guess_coordinate)] if guess_coordinate is not None else None, lat=[guess_coordinate.latitude] if guess_coordinate is not None else None, lon=[guess_coordinate.longitude] if guess_coordinate is not None else None, mode="markers", marker=go.scattermapbox.Marker( size=6, ), hoverinfo="text", hovertemplate='coord: %{customdata[0]}' )) fig.update_layout( mapbox_style="open-street-map", hovermode='closest', mapbox=dict( bearing=0, center=go.layout.mapbox.Center( lat=guess_coordinate.latitude if guess_coordinate is not None else 0, lon=guess_coordinate.longitude if guess_coordinate is not None else 0 ), pitch=0, zoom=3 if guess_coordinate is not None else 0 ), ) return fig