本文将引导您使用 TomTom Maps API 创建乘车请求应用程序。该应用程序将允许用户输入多个上车和下车地点,计算最佳路线并将其显示在地图上。我们将涵盖从获取 API 密钥到在地图上渲染优化路线的所有内容。
第 1 步:设置 TomTom API
在深入研究代码之前,您需要在 TomTom 开发人员门户上注册并获取 API 密钥。此密钥将允许您访问 TomTom 的服务,例如路线、地理编码和地图。
第 2 步:实现乘车请求功能
该应用程序的核心包括收集地址、将其转换为坐标并计算最佳路线。具体方法如下:
def ride_request(request): if request.method == 'POST': form = RideForm(request.POST) if form.is_valid(): ride = form.save(commit=False) # Get coordinates for the pickup and drop locations pickup_coords = get_coordinates(ride.pickup_address) pickup_coords_1 = get_coordinates(ride.pickup_address_1) pickup_coords_2 = get_coordinates(ride.pickup_address_2) drop_coords = get_coordinates(ride.drop_address) # Ensure all coordinates are available if all([pickup_coords, pickup_coords_1, pickup_coords_2, drop_coords]): # Set the coordinates ride.pickup_latitude, ride.pickup_longitude = pickup_coords ride.pickup_latitude_1, ride.pickup_longitude_1 = pickup_coords_1 ride.pickup_latitude_2, ride.pickup_longitude_2 = pickup_coords_2 ride.drop_latitude, ride.drop_longitude = drop_coords # Save the ride and redirect to the success page try: ride.save() return redirect('success_page', pickup_lon=ride.pickup_longitude, pickup_lat=ride.pickup_latitude, pickup_lon_1=ride.pickup_longitude_1, pickup_lat_1=ride.pickup_latitude_1, pickup_lon_2=ride.pickup_longitude_2, pickup_lat_2=ride.pickup_lat_2, drop_lon=ride.drop_longitude, drop_lat=ride.drop_latitude) except IntegrityError as e: messages.error(request, f'IntegrityError: {str(e)}') else: messages.error(request, 'Error getting coordinates. Please try again.') else: form = RideForm() return render(request, 'maps/ride_request.html', {'form': form})
在此代码片段中,应用程序接受多个地址的用户输入,使用 get_coordinates 函数将这些地址转换为坐标,并保存数据以供以后使用。
def get_coordinates(address): """ Get coordinates (latitude, longitude) for a given address using TomTom Geocoding API. """ api_key = 'YOUR_TOMTOM_API_KEY' base_url = 'https://api.tomtom.com/search/2/geocode/{address}.json' # Prepare the URL with the address and API key url = base_url.format(address=address) params = {'key': api_key} # Make the request to TomTom Geocoding API response = requests.get(url, params=params) data = response.json() # Check if the request was successful if response.status_code == 200 and data.get('results'): # Extract coordinates from the response result = data['results'][0] if 'position' in result: coordinates = result['position'] return coordinates.get('lat'), coordinates.get('lon') else: print( f"Error getting coordinates for {address}: 'position' key not found in the response.") return None else: # Handle errors or return a default value print( f"Error getting coordinates for {address}: {data.get('message')}") return None
第三步:计算优化路线
获得坐标后,下一步就是计算优化路线。 TomTom 的路点优化 API 有助于确定多个点之间最有效的路径。
def get_optimized_route(*pickup_coords, drop_coords): api_key = 'YOUR_TOMTOM_API_KEY' # Prepare the payload for the API payload = { 'waypoints': [{'point': {'latitude': lat, 'longitude': lon}} for lon, lat in pickup_coords], 'options': {'travelMode': 'car'}, } # Add the drop location to the waypoints payload['waypoints'].append({'point': {'latitude': drop_coords[1], 'longitude': drop_coords[0]}}) # API request response = requests.post(f'https://api.tomtom.com/routing/waypointoptimization/1', params={'key': api_key}, json=payload) if response.status_code == 200: data = response.json() if 'optimizedOrder' in data: # Extract the optimized route return [get_route_geometry(pickup_coords[i], pickup_coords[j]) for i, j in zip(data['optimizedOrder'], data['optimizedOrder'][1:])] return None
此函数向 TomTom API 发送请求,接收路径点的优化顺序,然后计算路线几何形状。
第 4 步:渲染地图和路线
最后,在获得优化的路线数据后,是时候在 success_page.html 上渲染地图了。
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Ride Request - Success</title> <link rel="stylesheet" href="{% static 'maps/css/styles.css' %}"> <!-- Include TomTom Map SDK --> <link rel="stylesheet" type="text/css" href="https://api.tomtom.com/maps-sdk-for-web/cdn/6.x/6.25.0/maps/maps.css" /> <script type="text/javascript" src="https://api.tomtom.com/maps-sdk-for-web/cdn/6.x/6.25.0/maps/maps-web.min.js"></script> </head> <body> <div class="container"> <div class="map-container" id="dynamic-map"></div> </div> <!-- Map Initialization Script --> <script type="text/javascript"> var map; var pickup_lon = {{ pickup_lon }}; var pickup_lat = {{ pickup_lat }}; var pickup_lon_1 = {{ pickup_lon_1 }}; var pickup_lat_1 = {{ pickup_lat_1 }}; var pickup_lon_2 = {{ pickup_lon_2 }}; var pickup_lat_2 = {{ pickup_lat_2 }}; var drop_lon = {{ drop_lon }}; var drop_lat = {{ drop_lat }}; var routeGeometry = {{ route_data.route_geometry| safe }}; var geomatryCoordinates = routeGeometry.geometry.coordinates; const API_KEY = 'YOUR_TOMTOM_API_KEY'; function initMap() { //let center = [(pickup_lat + drop_lat) / 2, (pickup_lon + drop_lon) / 2]; let center = [pickup_lon, pickup_lat]; console.log('center:', center) map = tt.map({ key: API_KEY, container: 'dynamic-map', //stylesVisibility: { // trafficIncidents: true //}, center: center, bearing: 0, maxZoom: 21, minZoom: 1, pitch: 60, zoom: 12, //style: `https://api.tomtom.com/style/1/style/*?map=2/basic_street-satellite&poi=2/poi_dynamic-satellite&key=${API_KEY}` }); map.addControl(new tt.FullscreenControl()); map.addControl(new tt.NavigationControl()); map.on('load', () => { console.log('Map loaded successfully!'); // Add markers for all pickup locations and drop location var pickupMarker = new tt.Marker({ color: 'green' }).setLngLat([pickup_lon, pickup_lat]).addTo(map); var pickupMarker1 = new tt.Marker({ color: 'blue' }).setLngLat([pickup_lon_1, pickup_lat_1]).addTo(map); var pickupMarker2 = new tt.Marker({ color: 'orange' }).setLngLat([pickup_lon_2, pickup_lat_2]).addTo(map); var dropMarker = new tt.Marker({ color: 'red' }).setLngLat([drop_lon, drop_lat]).addTo(map); try { // Iterate through each set of coordinates and add route layer geomatryCoordinates.forEach((coordinates, index) => { var routeGeometry = { type: 'Feature', geometry: { type: 'LineString', coordinates: coordinates, }, }; // Check if the routeGeometry is a valid GeoJSON object if (isValidGeoJSON(routeGeometry)) { map.addLayer({ 'id': `route-${index}`, 'type': 'line', 'source': { 'type': 'geojson', 'data': routeGeometry, }, 'layout': { 'line-join': 'round', 'line-cap': 'round', }, 'paint': { 'line-color': '#3887be', 'line-width': 8, 'line-opacity': 0.8, }, }); console.log(`Route layer ${index} added successfully!`); } else { console.error(`Invalid GeoJSON format for route ${index}. Creating a simple LineString.`); // Attempt to create a LineString GeoJSON var simpleRouteGeometry = { type: 'Feature', geometry: { type: 'LineString', coordinates: coordinates, }, }; map.addLayer({ 'id': `route-${index}`, 'type': 'line', 'source': { 'type': 'geojson', 'data': simpleRouteGeometry, }, 'layout': { 'line-join': 'round', 'line-cap': 'round', }, 'paint': { 'line-color': '#3887be', 'line-width': 8, 'line-opacity': 0.8, }, }); console.log(`Route layer ${index} added successfully with new GeoJSON.`); } }); } catch (error) { console.error('Error handling GeoJSON:', error); } function isValidGeoJSON(data) { return typeof data === 'object' && data !== null && data.type === 'Feature'; } initMap(); // Call the initMap function </script> </body> </html>
此 HTML 代码初始化 TomTom 地图,在上车点和下车点放置标记,并绘制它们之间的路线。
结果:乘车申请表和成功地图
注意:上面提供的代码是一个简化的示例,用于演示使用 TomTom 的 API 叫车和计算路线的基本功能。实际的实现可能有所不同,并包括基于特定要求的附加功能或变化。更多详细信息和高级使用方法,请参考 TomTom 官方开发者文档。
以上是如何使用 TomTom Maps API 创建多站路线优化应用程序的详细内容。更多信息请关注PHP中文网其他相关文章!