如何在.NET MAUI Blazor Hybrid中实现Google Maps导航功能
实现Google Maps实时导航的修改方案(Blazor物流应用)
你当前的代码仅渲染了两点间的静态路径,要实现实时导航(跟随用户位置、动态更新指引),需要补充实时位置跟踪、导航状态管理和交互控制,以下是具体修改步骤:
一、修正数据传递错误
当前C#端传递的origin是字符串格式,JS中访问origin.Latitude会报错,需改为传递结构化对象:
修改@code中的RequestLocationPermissionAndInitializeMap方法:
private async Task RequestLocationPermissionAndInitializeMap() { var status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>(); if (status == PermissionStatus.Granted) { var (location, locationFetchingError) = await locationService.GetCurrentLocationAsync(); // 传递结构化对象而非字符串,避免JS解析错误 var origin = new { Latitude = location.Latitude, Longitude = location.Longitude }; var destination = new { Latitude = 59.337017307552195, Longitude = 18.05017354381474 }; await JS.InvokeVoidAsync("initNavigation", origin, destination); } else { Console.WriteLine("位置权限被拒绝"); } }
二、添加实时导航核心功能
1. 更新HTML结构(添加控制按钮与信息面板)
<div class="card my-card"> <div id="map2" style="width: 100%; height: 400px"></div> <!-- 导航控制按钮 --> <div class="p-2 d-flex gap-2"> <button onclick="startNavigation()" class="btn btn-primary">开始导航</button> <button onclick="pauseNavigation()" class="btn btn-secondary">暂停</button> <button onclick="stopNavigation()" class="btn btn-danger">结束</button> </div> <!-- 实时导航信息 --> <div id="navigation-info" class="p-2"> <p>剩余距离: <span id="remaining-distance">-</span></p> <p>剩余时间: <span id="remaining-time">-</span></p> </div> <!-- 导航步骤面板 --> <div id="directions-panel" class="p-2 border-top"></div> </div>
2. 修改JS逻辑(添加位置跟踪与导航状态管理)
let map; let directionsService; let directionsRenderer; let watchId; // 位置监听ID let currentRoute; // 当前导航路线数据 let isNavigating = false; window.initNavigation = function (origin, destination) { map = new google.maps.Map(document.getElementById("map2"), { zoom: 15, center: { lat: origin.Latitude, lng: origin.Longitude }, disableDefaultUI: false, // 保留必要UI控件(如缩放) zoomControl: true, mapTypeControl: false, streetViewControl: false }); directionsService = new google.maps.DirectionsService(); directionsRenderer = new google.maps.DirectionsRenderer({ map: map, suppressMarkers: false, panel: document.getElementById("directions-panel") }); // 预先获取路线数据 const request = { origin: origin, destination: destination, travelMode: google.maps.TravelMode.DRIVING }; directionsService.route(request, function (result, status) { if (status === google.maps.DirectionsStatus.OK) { directionsRenderer.setDirections(result); currentRoute = result; showNavigationSteps(result); updateNavigationInfo(result); } else { console.error("路线请求失败: " + status); } }); } // 开始实时导航 function startNavigation() { if (isNavigating || !currentRoute) return; isNavigating = true; // 高精度监听位置变化 watchId = navigator.geolocation.watchPosition( (position) => { const currentLatLng = new google.maps.LatLng( position.coords.latitude, position.coords.longitude ); // 地图跟随当前位置 map.panTo(currentLatLng); // 更新当前导航步骤 updateCurrentStep(currentLatLng); }, (error) => { console.error("位置跟踪失败: " + error.message); stopNavigation(); }, { enableHighAccuracy: true, timeout: 5000, maximumAge: 0 } ); } // 暂停导航 function pauseNavigation() { if (!isNavigating) return; navigator.geolocation.clearWatch(watchId); isNavigating = false; } // 结束导航 function stopNavigation() { if (watchId) { navigator.geolocation.clearWatch(watchId); watchId = null; } isNavigating = false; } // 更新实时导航信息 function updateNavigationInfo(result) { const leg = result.routes[0].legs[0]; document.getElementById("remaining-distance").textContent = leg.distance.text; document.getElementById("remaining-time").textContent = leg.duration.text; } // 高亮当前所在导航步骤 function updateCurrentStep(currentLatLng) { const steps = currentRoute.routes[0].legs[0].steps; // 从后往前遍历,找到距离当前位置最近的步骤(误差50米内) for (let i = steps.length - 1; i >= 0; i--) { const stepLatLng = steps[i].end_location; const distance = google.maps.geometry.spherical.computeDistanceBetween( currentLatLng, stepLatLng ); if (distance < 50) { const panelItems = document.getElementById("directions-panel").children; Array.from(panelItems).forEach((item, index) => { item.style.backgroundColor = index === i ? "#e3f2fd" : "transparent"; }); break; } } } function showNavigationSteps(directionResult) { const steps = directionResult.routes[0].legs[0].steps; const directionsPanel = document.getElementById("directions-panel"); directionsPanel.innerHTML = ""; steps.forEach((step, index) => { const instructionElement = document.createElement("div"); instructionElement.className = "p-1 mb-1"; instructionElement.innerHTML = `${index + 1}. ${step.instructions}`; directionsPanel.appendChild(instructionElement); }); }
三、关键注意事项
- 需在Google Maps脚本引入时添加Geometry库(用于距离计算):
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"></script> - 位置跟踪仅在HTTPS环境下生效(本地localhost可正常测试)。
- 可根据需求自定义用户位置标记(替换Google默认标记)。
内容的提问来源于stack exchange,提问作者Ayesh Nipun
相关产品推荐
相关产品推荐

