# lugar_3.py # Gradio 6.2.0 # Layout FULL PAGE (sem margens laterais) # ✔ Busca por nome e coordenadas # ✔ Mapa Leaflet # ✔ Google Street View (fallback automático) # ✔ Apple Maps import re import html import requests import gradio as gr # ---------------------------- # Parsing / Geocoding # ---------------------------- _COORD_RE = re.compile( r""" ^\s* (?:lat\s*[:=]?\s*)?(-?\d+(?:\.\d+)?) (?:\s*[,;]\s*|\s+) (?:lon|lng|long)?\s*[:=]?\s*(-?\d+(?:\.\d+)?) \s*$ """, re.IGNORECASE | re.VERBOSE ) def parse_coords(text: str): if not text: return None m = _COORD_RE.match(text.strip()) if not m: return None lat = float(m.group(1)) lon = float(m.group(2)) if not (-90 <= lat <= 90 and -180 <= lon <= 180): raise ValueError("Coordenadas fora do intervalo válido.") return lat, lon def geocode_by_name(query: str): url = "https://nominatim.openstreetmap.org/search" params = {"q": query, "format": "jsonv2", "limit": 1} headers = {"User-Agent": "GradioMapFullPage"} r = requests.get(url, params=params, headers=headers, timeout=20) r.raise_for_status() data = r.json() if not data: raise ValueError(f"Local não encontrado: {query}") lat = float(data[0]["lat"]) lon = float(data[0]["lon"]) name = data[0].get("display_name", query) return lat, lon, name def resolve_location(mode, place, lat, lon): if mode == "coords": return float(lat), float(lon), f"{lat:.6f}, {lon:.6f}" if mode == "auto": parsed = parse_coords(place) if parsed: la, lo = parsed return la, lo, f"{la:.6f}, {lo:.6f}" return geocode_by_name(place) # ---------------------------- # Map HTML (srcdoc) # ---------------------------- def build_srcdoc(lat, lon, zoom, basemap, title): sv0 = f"https://www.google.com/maps/@?api=1&map_action=pano&viewpoint={lat:.7f},{lon:.7f}" a0 = f"https://maps.apple.com/place?coordinate={lat:.7f},{lon:.7f}" doc = f"""

{html.escape(title)}

Coordenadas: {lat:.7f}, {lon:.7f}
""" return html.escape(doc, quote=True) def run(mode, place, lat, lon, zoom, basemap): lat0, lon0, name = resolve_location(mode, place, lat, lon) srcdoc = build_srcdoc(lat0, lon0, zoom, basemap, f"📍 {name}") iframe = f'' return f"OK — {name}", iframe # ---------------------------- # UI (FULL PAGE) # ---------------------------- CSS = """ .gradio-container { max-width: 100% !important; padding-left: 0 !important; padding-right: 0 !important; } """ with gr.Blocks(css=CSS, title="Mapa Full Page") as demo: with gr.Row(): mode = gr.Radio(["auto", "nome", "coords"], value="auto", label="Modo") place = gr.Textbox(label="Local ou coordenadas", value="Lisboa") lat_in = gr.Number(label="Latitude", value=38.7223, precision=7) lon_in = gr.Number(label="Longitude", value=-9.1393, precision=7) basemap = gr.Dropdown(["Esri Satellite", "OSM"], value="Esri Satellite", label="Base map") zoom = gr.Slider(3, 20, value=16, label="Zoom") btn = gr.Button("Mostrar", variant="primary") status = gr.Textbox(label="Status", interactive=False) view = gr.HTML() btn.click(run, [mode, place, lat_in, lon_in, zoom, basemap], [status, view]) demo.load(lambda: run("auto", "Lisboa", 38.7223, -9.1393, 12, "Esri Satellite"), outputs=[status, view]) demo.launch()