定位地图 MiniApp
location 权限、坐标采样和 MapView 标记当前位置。
演示 location 权限、start_updates/get_location 与 appui.MapView 标记当前位置。
#预期效果
运行后会出现定位地图页,授权、坐标采样、地图标记和状态摘要在同一屏展示。
#完整示例
已复制
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模块。