增加导航
This commit is contained in:
机械小鸽 2025-03-28 23:54:06 +08:00 committed by GitHub
parent 779c2d32c4
commit 044e8371a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 907 additions and 22 deletions

View File

@ -281,6 +281,16 @@ def amap_addr_input():
amap_key, amap_key_2 = fleet.get_amap_key()
return render_template("amap_addr_input.html", lon=lon, lat=lat, amap_key=amap_key, amap_key_2=amap_key_2)
@app.route("/tmap_addr_input", methods=['GET', 'POST'])
def tmap_addr_input():
if request.method == 'POST':
postvars = request.form.to_dict()
fleet.nav_confirmed(postvars)
return redirect(url_for('tmap_addr_input'))
else:
lon, lat = fleet.get_last_lon_lat()
return render_template("tmap_addr_input.html", lon=lon, lat=lat)
@app.route("/CurrentStep.json", methods=['GET'])
def find_CurrentStep():
directory = "/data/openpilot/selfdrive/manager/"
@ -336,6 +346,34 @@ def store_toggle_values_route():
except Exception as e:
return jsonify({"error": "Failed to update values", "details": str(e)}), 400
@app.route("/get_nav_status", methods=['GET'])
def get_nav_status():
nav_active = fleet.get_nav_active()
return jsonify({
"active": nav_active
})
@app.route("/get_system_status", methods=['GET'])
def get_system_status():
nav_active = fleet.get_nav_active()
gps_status = fleet.get_gps_status()
network_status = fleet.check_network_status()
return jsonify({
"nav_status": {
"active": nav_active,
"state": "导航中" if nav_active else "待机"
},
"gps_status": {
"active": gps_status["active"],
"signal": gps_status["signal"]
},
"network_status": {
"connected": network_status["connected"],
"type": network_status["type"]
}
})
def main():
try:
set_core_affinity([0, 1, 2, 3])

View File

@ -221,9 +221,10 @@ def ffplay_mp4_wrap_process_builder(file_name):
)
def get_nav_active():
if params.get("NavDestination", encoding='utf8') is not None:
return True
else:
try:
with open('/data/params/d/NavDestination', 'r') as f:
return f.read().strip() != ""
except:
return False
def get_public_token():
@ -244,20 +245,29 @@ def get_amap_key():
return (token.strip() if token is not None else None, token2.strip() if token2 is not None else None)
def get_SearchInput():
SearchInput = params.get_int("SearchInput")
return SearchInput
try:
with open('/data/params/d/SearchInput', 'r') as f:
return int(f.read())
except:
return 0
def get_PrimeType():
PrimeType = params.get_int("PrimeType")
return PrimeType
try:
with open('/data/params/d/PrimeType', 'r') as f:
return int(f.read())
except:
return 0
def get_last_lon_lat():
last_pos = params.get("LastGPSPosition")
if last_pos:
l = json.loads(last_pos)
else:
return 0.0, 0.0
return l["longitude"], l["latitude"]
try:
with open('/data/params/d/LastGPSPosition', 'r') as f:
content = f.read().strip()
if content:
lat, lon = map(float, content.split(","))
return lon, lat
except:
pass
return 116.397128, 39.916527 # 默认北京天安门坐标
def get_locations():
data = params.get("ApiCache_NavDestinations", encoding='utf-8')
@ -463,3 +473,30 @@ def store_toggle_values(updated_values):
params_memory.put_bool("FrogPilotTogglesUpdated", True)
time.sleep(1)
params_memory.put_bool("FrogPilotTogglesUpdated", False)
def get_gps_status():
try:
# 读取GPS状态
with open('/data/params/d/LastGPSPosition', 'r') as f:
content = f.read().strip()
if not content:
return {"active": False, "signal": "无信号"}
return {
"active": True,
"signal": "正常"
}
except:
return {"active": False, "signal": "未知"}
def check_network_status():
try:
# 检查网络连接
result = subprocess.run(['ping', '-c', '1', '-W', '1', '8.8.8.8'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
return {
"connected": result.returncode == 0,
"type": "已连接" if result.returncode == 0 else "未连接"
}
except:
return {"connected": False, "type": "未知"}

View File

@ -1,16 +1,146 @@
{% extends "layout.html" %}
{% block title %}
Home
Fleet Manager 主页
{% endblock %}
{% block main %}
<br>
<h1>Fleet Manager</h1>
<br>
<a href='/footage'>View Dashcam Footage</a><br>
<br><a href='/preserved'>Access Preserved Footage</a><br>
<br><a href='/screenrecords'>View Screen Recordings</a><br>
<br><a href='/error_logs'>Access Error Logs</a><br>
<br><a href='/about'>About Fleet Manager</a><br>
<!-- UIkit CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.9.2/dist/css/uikit.min.css" />
<!-- UIkit JS -->
<script src="https://cdn.jsdelivr.net/npm/uikit@3.9.2/dist/js/uikit.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/uikit@3.9.2/dist/js/uikit-icons.min.js"></script>
<div class="uk-container uk-container-small">
<h1 class="uk-heading-medium uk-text-center uk-margin-medium-top">Fleet Manager</h1>
<!-- 导航部分 -->
<div class="uk-card uk-card-default uk-card-body uk-margin-medium">
<h3 class="uk-card-title">导航服务</h3>
<div class="uk-grid-small uk-child-width-1-2@s uk-text-center" uk-grid>
<div>
<a href="/addr_input" class="uk-button uk-button-primary uk-width-1-1">
<span uk-icon="location"></span> 地址输入导航
</a>
</div>
<div>
<a href="/amap_addr_input" class="uk-button uk-button-primary uk-width-1-1">
<span uk-icon="location"></span> 高德地图导航
</a>
</div>
<div>
<a href="/tmap_addr_input" class="uk-button uk-button-primary uk-width-1-1">
<span uk-icon="location"></span> 腾讯地图导航
</a>
</div>
<div>
<a href="/tools" class="uk-button uk-button-secondary uk-width-1-1">
<span uk-icon="settings"></span> 系统设置
</a>
</div>
</div>
</div>
<!-- 视频和日志部分 -->
<div class="uk-card uk-card-default uk-card-body uk-margin-medium">
<h3 class="uk-card-title">视频和日志</h3>
<div class="uk-grid-small uk-child-width-1-2@s uk-text-center" uk-grid>
<div>
<div class="uk-card uk-card-default uk-card-body uk-box-shadow-small">
<h4>视频记录</h4>
<a href="/footage" class="uk-button uk-button-default uk-width-1-1 uk-margin-small-bottom">
<span uk-icon="video-camera"></span> 查看行车记录
</a>
<a href="/preserved" class="uk-button uk-button-default uk-width-1-1 uk-margin-small-bottom">
<span uk-icon="album"></span> 已保存视频
</a>
<a href="/screenrecords" class="uk-button uk-button-default uk-width-1-1">
<span uk-icon="desktop"></span> 屏幕录制
</a>
</div>
</div>
<div>
<div class="uk-card uk-card-default uk-card-body uk-box-shadow-small">
<h4>系统日志</h4>
<a href="/error_logs" class="uk-button uk-button-default uk-width-1-1 uk-margin-small-bottom">
<span uk-icon="warning"></span> 错误日志
</a>
<a href="/about" class="uk-button uk-button-default uk-width-1-1">
<span uk-icon="info"></span> 关于系统
</a>
</div>
</div>
</div>
</div>
<!-- 系统状态部分 -->
<div class="uk-card uk-card-default uk-card-body uk-margin-medium">
<h3 class="uk-card-title">系统状态</h3>
<div id="system-status" class="uk-grid-small uk-child-width-1-3@s uk-text-center" uk-grid>
<div>
<div class="uk-card uk-card-default uk-card-body uk-box-shadow-small">
<h4>导航状态</h4>
<div id="nav-status">
<span class="uk-label uk-label-warning">待机</span>
</div>
</div>
</div>
<div>
<div class="uk-card uk-card-default uk-card-body uk-box-shadow-small">
<h4>GPS信号</h4>
<div id="gps-status">
<span class="uk-label uk-label-warning">检测中</span>
</div>
</div>
</div>
<div>
<div class="uk-card uk-card-default uk-card-body uk-box-shadow-small">
<h4>网络状态</h4>
<div id="network-status">
<span class="uk-label uk-label-warning">检测中</span>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// 定期更新系统状态
function updateSystemStatus() {
fetch('/get_system_status')
.then(response => response.json())
.then(data => {
// 更新导航状态
document.getElementById('nav-status').innerHTML =
`<span class="uk-label ${data.nav_status.active ? 'uk-label-success' : 'uk-label-warning'}">
${data.nav_status.state}
</span>`;
// 更新GPS状态
document.getElementById('gps-status').innerHTML =
`<span class="uk-label ${data.gps_status.active ? 'uk-label-success' : 'uk-label-warning'}">
${data.gps_status.signal}
</span>`;
// 更新网络状态
document.getElementById('network-status').innerHTML =
`<span class="uk-label ${data.network_status.connected ? 'uk-label-success' : 'uk-label-warning'}">
${data.network_status.type}
</span>`;
})
.catch(error => {
console.error('Error:', error);
// 发生错误时显示错误状态
['nav-status', 'gps-status', 'network-status'].forEach(id => {
document.getElementById(id).innerHTML =
`<span class="uk-label uk-label-danger">错误</span>`;
});
});
}
// 每5秒更新一次状态
setInterval(updateSystemStatus, 5000);
updateSystemStatus(); // 初始更新
</script>
{% endblock %}

View File

@ -0,0 +1,680 @@
{% extends "layout.html" %}
{% block title %}
腾讯地图导航
{% endblock %}
{% block main %}
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<title>地点搜索与导航</title>
<!-- UIkit CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.9.2/dist/css/uikit.min.css" />
<!-- UIkit JS -->
<script src="https://cdn.jsdelivr.net/npm/uikit@3.9.2/dist/js/uikit.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/uikit@3.9.2/dist/js/uikit-icons.min.js"></script>
<style type="text/css">
body {
margin: 0;
height: 100%;
width: 100%;
position: absolute;
}
#mapContainer {
width: 100%;
height: 80vh;
position: relative;
}
.search-box {
position: absolute;
top: 20px;
left: 20px;
right: 20px;
z-index: 999;
background: white;
padding: 10px;
border-radius: 3px;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.search-results {
position: absolute;
top: 80px;
left: 20px;
right: 20px;
z-index: 998;
background: white;
border-radius: 3px;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
max-height: 300px;
overflow-y: auto;
display: none;
}
.search-result-item {
padding: 10px;
border-bottom: 1px solid #eee;
cursor: pointer;
}
.search-result-item:hover {
background-color: #f5f5f5;
}
</style>
<div class="search-box">
<div class="uk-grid-small" uk-grid>
<div class="uk-width-1-4">
<select id="save_type" class="uk-select">
<option value="recent">最近</option>
<option value="home">住家</option>
<option value="work">工作</option>
</select>
</div>
<div class="uk-width-expand">
<div class="uk-inline uk-width-1-1">
<span class="uk-form-icon" uk-icon="icon: search"></span>
<input class="uk-input" type="text" id="keyword"
placeholder="请输入关键字搜索地点"
autocomplete="off">
</div>
</div>
<div class="uk-width-auto">
<button class="uk-button uk-button-primary" onclick="searchPlace(document.getElementById('keyword').value)">
<span uk-icon="icon: search"></span> 搜索
</button>
</div>
</div>
<div class="uk-margin-small-top">
<button class="uk-button uk-button-default uk-button-small" onclick="locateUser()">
<span uk-icon="icon: location"></span> 定位
</button>
<button class="uk-button uk-button-default uk-button-small" onclick="showSearchHistory()">
<span uk-icon="icon: history"></span> 历史记录
</button>
</div>
</div>
<div id="search-results" class="search-results"></div>
<div id="mapContainer"></div>
<!-- 更改腾讯地图API引入方式增加passive参数可能会减少一些警告 -->
<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&key=BDMBZ-LZQ63-GUG37-OCHES-2ESXV-Q5BVC&libraries=geometry"></script>
<script type="text/javascript">
var map, marker, infoWindow;
var searchTimeout;
var searchMarkers = [];
var initialPosition;
// 修复标记图片URL问题 - 使用腾讯地图官方正确的图标URL
var markerIconDefault = 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/marker.png';
var markerIconSelected = 'https://mapapi.qq.com/web/lbs/javascriptV2/javascript/img/marker_red.png';
var markerIconSearch = 'https://mapapi.qq.com/web/lbs/javascriptV2/javascript/img/marker_blue.png';
// 初始化地图
function initMap() {
// 修复Jinja变量语法避免JavaScript解析错误
initialPosition = new TMap.LatLng(Number("{{lat}}"), Number("{{lon}}"));
map = new TMap.Map('mapContainer', {
center: initialPosition,
zoom: 15,
showControl: true,
viewMode: '2D' // 明确指定2D模式可能会减少一些警告
});
// 添加当前位置标记 - 使用正确的图标URL
marker = new TMap.MultiMarker({
map: map,
styles: {
"marker": new TMap.MarkerStyle({
width: 25,
height: 35,
anchor: { x: 12.5, y: 35 },
src: markerIconDefault
}),
"selected": new TMap.MarkerStyle({
width: 30,
height: 42,
anchor: { x: 15, y: 42 },
src: markerIconSelected
}),
"searchResult": new TMap.MarkerStyle({
width: 25,
height: 35,
anchor: { x: 12.5, y: 35 },
src: markerIconSearch
})
},
geometries: [{
id: 'current',
position: initialPosition,
styleId: 'marker'
}]
});
// 添加点击事件
map.on('click', handleMapClick);
// 初始化搜索服务
initSearchService();
}
// 初始化搜索服务和联想功能
function initSearchService() {
// 监听输入框,实现联想搜索
var inputElement = document.getElementById('keyword');
inputElement.addEventListener('input', function() {
var keyword = this.value.trim();
if (keyword) {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(function() {
searchSuggestion(keyword);
}, 300);
} else {
document.getElementById('search-results').style.display = 'none';
}
});
// 防止表单提交刷新页面
inputElement.form && inputElement.form.addEventListener('submit', function(e) {
e.preventDefault();
searchPlace(inputElement.value);
});
}
// 处理地图点击
function handleMapClick(evt) {
var position = evt.latLng;
// 清除搜索结果
document.getElementById('search-results').style.display = 'none';
// 更新标记位置
marker.updateGeometries([{
id: 'current',
position: position,
styleId: 'marker'
}]);
// 对于地图点击,设置一个默认地名 "选定位置"
var coordsText = "(" + position.lat.toFixed(6) + ", " + position.lng.toFixed(6) + ")";
showInfoWindow(position, "选定位置", coordsText);
}
// 显示信息窗口 - 使用搜索框文本作为地名
function showInfoWindow(position, name, addr) {
if (infoWindow) {
infoWindow.close();
}
// 获取搜索框的值作为地名
var searchText = document.getElementById('keyword').value.trim();
var placeName = searchText || name || "选定位置";
// 调试输出
console.log("显示信息窗口,搜索框文本:", searchText, "名称:", name, "地址:", addr, "使用地名:", placeName);
infoWindow = new TMap.InfoWindow({
map: map,
position: position,
content: `
<div class="uk-card uk-card-default uk-card-body" style="padding:10px; min-width:200px;">
<a class="uk-card-badge uk-label" onClick="javascript:infoWindow.close()" uk-close></a>
<h3 style="padding-top: 10px;" class="uk-card-title">${name || ""}</h3>
<p>${addr || ""}</p>
<div class="uk-card-footer" style="padding-top:10px;">
<form name="navForm" method="post">
<input type="hidden" name="lat" value="${position.lat}">
<input type="hidden" name="lon" value="${position.lng}">
<input type="hidden" name="save_type" value="${document.getElementById('save_type').value}">
<input type="hidden" name="place_name" value="${placeName}">
<input class="uk-button uk-button-primary" type="submit" value="导航" onclick="console.log('导航表单提交,地点名:', '${placeName}')">
</form>
</div>
</div>
`,
offset: { x: 0, y: -35 }
});
}
// 修改搜索联想函数,添加错误处理
function searchSuggestion(keyword) {
console.log("搜索联想:", keyword);
// 避免使用可能导致跨域问题的XMLHttpRequest
// 直接使用JSONP方法这是最可靠的
var script = document.createElement('script');
var callbackName = 'jsonp_suggestion_' + Math.round(100000 * Math.random());
window[callbackName] = function(res) {
console.log("联想搜索结果:", res);
if (script.parentNode) document.body.removeChild(script);
delete window[callbackName];
if (res.status === 0 && res.data && res.data.length > 0) {
showSuggestionResults(res.data);
} else {
document.getElementById('search-results').style.display = 'none';
}
};
var suggestUrl = "https://apis.map.qq.com/ws/place/v1/suggestion?keyword=" +
encodeURIComponent(keyword) +
"&key=BDMBZ-LZQ63-GUG37-OCHES-2ESXV-Q5BVC&output=jsonp&callback=" + callbackName;
script.src = suggestUrl;
document.body.appendChild(script);
// 添加超时处理
setTimeout(function() {
if (window[callbackName]) {
console.error("联想搜索请求超时");
document.getElementById('search-results').style.display = 'none';
if (script.parentNode) document.body.removeChild(script);
delete window[callbackName];
}
}, 5000);
}
// 显示搜索联想结果
function showSuggestionResults(results) {
var container = document.getElementById('search-results');
container.innerHTML = '';
if (results && results.length > 0) {
results.forEach(function(result) {
var div = document.createElement('div');
div.className = 'search-result-item';
div.innerHTML = `
<div class="uk-text-bold">${result.title}</div>
<div class="uk-text-small uk-text-muted">${result.address || ''}</div>
`;
div.onclick = function() {
// 获取详细信息
getPlaceDetail(result.id);
};
container.appendChild(div);
});
container.style.display = 'block';
} else {
container.style.display = 'none';
}
}
// 修改搜索函数,添加错误处理
function searchPlace(keyword) {
if (!keyword || keyword.trim() === '') {
UIkit.notification({
message: '请输入搜索关键词',
status: 'warning',
pos: 'top-center',
timeout: 3000
});
return;
}
// 显示加载提示和调试信息
console.log("开始搜索:", keyword);
UIkit.notification({
message: '正在搜索...',
status: 'primary',
pos: 'top-center',
timeout: 2000
});
// 使用唯一的回调函数名称避免冲突
var callbackName = 'jsonp_search_' + Math.round(100000 * Math.random());
var script = document.createElement('script');
window[callbackName] = function(res) {
console.log("搜索结果:", res);
if (script.parentNode) document.body.removeChild(script);
delete window[callbackName];
if (res.status === 0 && res.data && res.data.length > 0) {
// 转换返回的数据格式
var places = res.data.map(function(item) {
return {
id: item.id,
title: item.title,
address: item.address,
location: {
lat: item.location.lat,
lng: item.location.lng
}
};
});
// 显示搜索结果列表
showSearchResults(places);
// 在地图上显示多个标记点
showMultipleMarkers(places);
// 调整地图视野以包含所有结果
fitMapToBounds(places);
} else {
UIkit.notification({
message: '未找到相关结果',
status: 'warning',
pos: 'top-center',
timeout: 3000
});
}
};
var searchUrl = "https://apis.map.qq.com/ws/place/v1/search?keyword=" +
encodeURIComponent(keyword) +
"&boundary=region(全国,0)" +
"&page_size=10" +
"&page_index=1" +
"&key=BDMBZ-LZQ63-GUG37-OCHES-2ESXV-Q5BVC&output=jsonp&callback=" + callbackName;
script.src = searchUrl;
document.body.appendChild(script);
// 添加超时处理
setTimeout(function() {
if (window[callbackName]) {
console.error("搜索请求超时");
UIkit.notification({
message: '搜索超时,请重试',
status: 'danger',
pos: 'top-center',
timeout: 3000
});
if (script.parentNode) document.body.removeChild(script);
delete window[callbackName];
}
}, 5000);
}
// 修改获取地点详情函数
function getPlaceDetail(id) {
var detailUrl = "https://apis.map.qq.com/ws/place/v1/detail?id=" +
encodeURIComponent(id) +
"&key=BDMBZ-LZQ63-GUG37-OCHES-2ESXV-Q5BVC&output=jsonp&callback=detailCallback";
var script = document.createElement('script');
script.src = detailUrl;
document.body.appendChild(script);
// 定义全局回调函数
window.detailCallback = function(res) {
console.log("地点详情:", res);
document.body.removeChild(script);
if (res.status === 0 && res.data) {
// 转换数据格式
var place = {
id: res.data.id,
title: res.data.title,
address: res.data.address,
location: {
lat: res.data.location.lat,
lng: res.data.location.lng
}
};
selectPlace(place);
} else {
UIkit.notification({
message: '获取地点详情失败',
status: 'danger',
pos: 'top-center',
timeout: 3000
});
}
};
}
// 选择地点
function selectPlace(place) {
var position = new TMap.LatLng(place.location.lat, place.location.lng);
// 更新地图视图
map.setCenter(position);
map.setZoom(16);
// 更新标记
marker.updateGeometries([{
id: 'current',
position: position,
styleId: 'selected'
}]);
// 显示信息窗口
showInfoWindow(position, place.title, place.address);
// 保存到历史记录
saveSearchHistory(place);
// 隐藏搜索结果
document.getElementById('search-results').style.display = 'none';
}
// 在地图上显示多个标记点 - 修复图标URL
function showMultipleMarkers(places) {
// 清除之前的搜索结果标记
clearSearchMarkers();
console.log("显示多个标记点:", places.length);
// 准备新的标记点数据
var geometries = [];
places.forEach(function(place, index) {
// 确保所有必要属性存在
if (!place.location || !place.location.lat || !place.location.lng) {
console.error("地点数据不完整:", place);
return;
}
var position = new TMap.LatLng(place.location.lat, place.location.lng);
geometries.push({
id: 'search_' + index,
position: position,
styleId: 'searchResult',
properties: {
title: place.title || "",
address: place.address || ""
}
});
});
console.log("创建几何标记:", geometries.length);
// 创建新的标记点图层 - 使用正确的图标URL
if (geometries.length > 0) {
try {
var searchResultMarker = new TMap.MultiMarker({
map: map,
styles: {
"searchResult": new TMap.MarkerStyle({
width: 25,
height: 35,
anchor: { x: 12.5, y: 35 },
src: markerIconSearch
})
},
geometries: geometries
});
// 添加点击事件
searchResultMarker.on('click', function(evt) {
var properties = evt.geometry.properties;
var position = evt.geometry.position;
// 显示信息窗口
showInfoWindow(position, properties.title, properties.address);
// 更新当前选中标记
marker.updateGeometries([{
id: 'current',
position: position,
styleId: 'selected'
}]);
});
// 保存到搜索标记数组
searchMarkers.push(searchResultMarker);
console.log("标记创建成功");
} catch (error) {
console.error("创建标记时出错:", error);
}
}
}
// 清除搜索结果标记
function clearSearchMarkers() {
searchMarkers.forEach(function(markerLayer) {
markerLayer.setMap(null);
});
searchMarkers = [];
}
// 调整地图视野以包含所有结果
function fitMapToBounds(places) {
if (!places || places.length === 0) return;
// 如果只有一个结果,直接定位到该位置
if (places.length === 1) {
var position = new TMap.LatLng(places[0].location.lat, places[0].location.lng);
map.setCenter(position);
map.setZoom(16);
return;
}
// 计算包含所有结果的视野范围
var bounds = new TMap.LatLngBounds();
places.forEach(function(place) {
bounds.extend(new TMap.LatLng(place.location.lat, place.location.lng));
});
// 设置地图视野
map.fitBounds(bounds, {
padding: 100 // 设置边距,避免标记点太靠近边缘
});
}
// 显示搜索结果 - 修复版本
function showSearchResults(results) {
console.log("显示搜索结果列表:", results.length);
var container = document.getElementById('search-results');
container.innerHTML = '';
if (results && results.length > 0) {
results.forEach(function(result) {
var div = document.createElement('div');
div.className = 'search-result-item';
div.innerHTML = `
<div class="uk-text-bold">${result.title || ""}</div>
<div class="uk-text-small uk-text-muted">${result.address || ""}</div>
`;
div.onclick = function() {
selectSearchResult(result);
};
container.appendChild(div);
});
container.style.display = 'block';
} else {
container.style.display = 'none';
}
}
// 添加用户定位功能
function locateUser() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
const userPosition = new TMap.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(userPosition);
marker.updateGeometries([{
id: 'current',
position: userPosition,
styleId: 'selected'
}]);
},
(error) => {
UIkit.notification({
message: '无法获取您的位置,请检查位置权限',
status: 'warning',
pos: 'top-center',
timeout: 3000
});
}
);
} else {
UIkit.notification({
message: '您的浏览器不支持地理定位',
status: 'danger',
pos: 'top-center',
timeout: 3000
});
}
}
// 添加历史记录功能
function saveSearchHistory(item) {
let history = JSON.parse(localStorage.getItem('searchHistory') || '[]');
// 避免重复添加
history = history.filter(h => h.title !== item.title);
history.unshift(item);
// 最多保存10条记录
if (history.length > 10) history.pop();
localStorage.setItem('searchHistory', JSON.stringify(history));
}
function showSearchHistory() {
const history = JSON.parse(localStorage.getItem('searchHistory') || '[]');
if (history.length > 0) {
showSearchResults(history);
}
}
// 选择搜索结果 - 确保title正确传递
function selectSearchResult(result) {
// 调试输出
console.log("选择搜索结果:", result);
const position = new TMap.LatLng(result.location.lat, result.location.lng);
// 更新地图视图
map.setCenter(position);
map.setZoom(16);
// 更新标记
marker.updateGeometries([{
id: 'current',
position: position,
styleId: 'selected'
}]);
// 确保传递完整的title和address
showInfoWindow(position, result.title || "", result.address || "");
// 保存到历史记录
saveSearchHistory(result);
// 隐藏搜索结果
document.getElementById('search-results').style.display = 'none';
}
// 初始化地图
initMap();
</script>
{% endblock %}