>백엔드 개발 >파이썬 튜토리얼 >TomTom Maps API를 사용하여 다중 경유지 경로 최적화 애플리케이션을 만드는 방법

TomTom Maps API를 사용하여 다중 경유지 경로 최적화 애플리케이션을 만드는 방법

WBOY
WBOY원래의
2024-08-14 18:50:02317검색

이 게시물에서는 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

3단계: 최적화된 경로 계산
좌표를 확보한 후 다음 단계는 최적화된 경로를 계산하는 것입니다. TomTom의 Waypoint Optimization 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 지도를 초기화하고 승하차 지점에 마커를 배치하고 두 지점 사이의 경로를 그립니다.

결과: 탑승 요청 양식 및 성공 지도

How to Create a Multi-Stop Route Optimization Application with TomTom Maps API

How to Create a Multi-Stop Route Optimization Application with TomTom Maps API

참고: 위에 제공된 코드는 TomTom의 API를 사용하여 탑승을 요청하고 경로를 계산하는 기본 기능을 보여주기 위한 간단한 예입니다. 실제 구현은 다를 수 있으며 특정 요구 사항에 따른 추가 기능이나 변형이 포함될 수 있습니다. 자세한 내용과 고급 사용법은 공식 TomTom 개발자 문서를 참조하세요.

위 내용은 TomTom Maps API를 사용하여 다중 경유지 경로 최적화 애플리케이션을 만드는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.