""" Röntgen tile server for sloppy maps. """ import logging from http.server import BaseHTTPRequestHandler, HTTPServer from pathlib import Path from typing import Optional import cairosvg from roentgen.tile import Tile from roentgen.workspace import workspace __author__ = "Sergey Vartanov" __email__ = "me@enzet.ru" class Handler(BaseHTTPRequestHandler): """ HTTP request handler that process sloppy map tile requests. """ def __init__( self, request: bytes, client_address: tuple[str, int], server ) -> None: super().__init__(request, client_address, server) self.cache: Path = Path("cache") self.update_cache: bool = False def do_GET(self) -> None: """Serve a GET request.""" parts: list[str] = self.path.split("/") if not (len(parts) == 5 and not parts[0] and parts[1] == "tiles"): return zoom: int = int(parts[2]) x: int = int(parts[3]) y: int = int(parts[4]) tile_path: Path = workspace.get_tile_path() png_path = tile_path / f"tile_{zoom}_{x}_{y}.png" if self.update_cache: svg_path = tile_path / f"tile_{zoom}_{x}_{y}.svg" if not png_path.exists(): if not svg_path.exists(): tile = Tile(x, y, zoom) tile.draw(tile_path, self.cache) cairosvg.svg2png(file_obj=svg_path, write_to=str(png_path)) logging.info(f"SVG file is rasterized to {png_path}.") if zoom != 18: return if png_path.exists(): with png_path.open("rb") as input_file: self.send_response(200) self.send_header("Content-type", "image/png") self.end_headers() self.wfile.write(input_file.read()) return def ui(options) -> None: """Command-line interface for tile server.""" server: Optional[HTTPServer] = None try: port: int = 8080 server: HTTPServer = HTTPServer(("", port), Handler) server.cache_path = Path(options.cache) server.serve_forever() logging.info(f"Server started on port {port}.") finally: if server: server.socket.close()