PythonIDE Docs
中文
简体中文

定位地图 MiniApp

location 权限、坐标采样和 MapView 标记当前位置。

演示 location 权限、start_updates/get_locationappui.MapView 标记当前位置。

#预期效果

运行后会出现定位地图页,授权、坐标采样、地图标记和状态摘要在同一屏展示。

#完整示例

python
import time

import appui
import location
import permission


DEFAULT_LAT = 31.2304
DEFAULT_LON = 121.4737

state = appui.State(
    status="未定位",
    latitude=DEFAULT_LAT,
    longitude=DEFAULT_LON,
    accuracy="--",
    authorized=False,
)


def refresh_location():
    timeout = 10.0
    state.status = "正在请求定位权限..."

    auth = location.authorization_status()
    if auth in ("denied", "restricted"):
        state.authorized = False
        state.status = "定位权限不可用,请到系统设置允许定位"
        return

    location.request_access()

    deadline = time.time() + timeout
    while time.time() < deadline:
        auth = location.authorization_status()
        if auth in ("denied", "restricted"):
            state.authorized = False
            state.status = "定位权限不可用,请到系统设置允许定位"
            return
        if auth not in ("not_determined", "unknown"):
            break
        time.sleep(0.25)

    state.status = "正在定位..."
    location.start_updates()
    time.sleep(0.5)
    try:
        while time.time() < deadline:
            loc = location.get_location()
            if loc and loc.get("latitude") is not None:
                state.authorized = True
                state.latitude = float(loc.get("latitude", DEFAULT_LAT))
                state.longitude = float(loc.get("longitude", DEFAULT_LON))
                state.accuracy = f"{float(loc.get('accuracy', 0.0)):.0f} m"
                state.status = "定位成功"
                return
            time.sleep(0.35)
    finally:
        location.stop_updates()

    state.authorized = False
    state.status = "暂未获得坐标,请稍后重试"


def body():
    marker = {
        "latitude": state.latitude,
        "longitude": state.longitude,
        "title": "当前位置",
    }
    return appui.NavigationStack(
        appui.List(
            [
                appui.Section(
                    [
                        appui.MapView(
                            latitude=state.latitude,
                            longitude=state.longitude,
                            span=0.02,
                            markers=[marker],
                        ).frame(height=280),
                    ],
                    header="地图",
                ),
                appui.Section(
                    [
                        appui.LabeledContent("状态", value=state.status),
                        appui.LabeledContent("纬度", value=f"{state.latitude:.5f}"),
                        appui.LabeledContent("经度", value=f"{state.longitude:.5f}"),
                        appui.LabeledContent("精度", value=state.accuracy),
                    ],
                    header="当前位置",
                ),
                appui.Section(
                    [
                        appui.Button("刷新定位", action=refresh_location)
                            .button_style("bordered_prominent"),
                    ],
                    footer="真机测试最可靠;模拟器需要先设置模拟位置。",
                ),
            ]
        ).navigation_title("定位地图")
    )


appui.run(body, state=state, presentation="fullscreen_with_close")

#关键技巧

  • request_access 后需 start_updates() 再轮询 get_location();读完后记得 stop_updates()
  • 首次 get_location() 常为 None,用状态文案提示“正在定位”并可重试。
  • 固定地点展示可只用 MapView,不必接 location 模块。