Skip to main content
Guzergah Optimizasyon API: 50 Satir Kodla Teslimat Maliyetlerini
Tutorials

Guzergah Optimizasyon API: 50 Satir Kodla Teslimat Maliyetlerini

Cok duraklı teslimat guzergahlarini optimize etmek, zaman pencereleri uygulamak, AB Dusuk Emisyon Bolgeleri'nden kacınmak ve sonucu 50 satir kodla haritada gostermek

Brent van der Heiden9 min read
#route optimization#delivery route#routing api#last mile delivery#multi-stop route#logistics api

Son mil dağıtım, herhangi bir tedarik zincirinin en pahalı kısmıdır. Endüstri ölçütlerine göre son mil maliyetleri toplam nakliye maliyetinin yüzde 53'ü tutarındadır. Bu içinde, kontrol edilebilen en büyük değişken rota verimliliğidir. Bir şoför 15 durağı yanlış sırada tamamlarsa, gerekenden yüzde 40 daha fazla kilometre sürür, yakıt yakar, aracı aşındırır ve yeniden teslimat ücretlerini tetikleyen teslimat zaman pencerelerini kaçırır.

Rota optimizasyonu artık kodda çözmesi zor bir problem değildir. Pahalı uzman lojistik yazılımı gerektiren şey şimdi bir API çağrısıdır. Bu eğitim, MapAtlas Routing API kullanarak tam bir çok durak rota optimizeri oluşturur: teslimat durağı listesi gönderen bir Python betiği, toplam mesafe ve saat ile optimize edilmiş sıra alır, zaman penceresi kısıtlamaları uygular ve kentsel teslimatlar için AB Düşük Emisyon Bölgesi kısıtlamalarını işler. Bir JavaScript parçası daha sonra sonucu haritada çizer.

Python uygulaması 55 satırdan az. JavaScript harita görüntüsü ek olarak 30 satır.

Son Mil Maliyet Sorunu

Optimizasyonun gerçekte ne kadar tasarruf sağladığını anlamak için, gerçekçi bir teslimat senaryosu için sayıları çalıştırın:

  • Fleet: 10 vans
  • Stops per van per day: 18
  • Current average distance: 210 km/van/day
  • Fuel cost: €0.38/km (diesel, EU average)
  • Driver cost: €22/hour
  • Average current route time: 7.5 hours/day

Van başına günlük cari maliyet: (210 × €0.38) + (7.5 × €22) = €79.80 + €165 = €244.80/van/gün

Yüzde 30 mesafe azalması (yoğun bir kentsel ağda iyi optimizasyon ile başarılabilir) ve yüzde 20 zaman tasarrufu üretir:

  • Optimize mesafe: 147 km → yakıt maliyeti: €55.86
  • Optimize saat: 6 saat → şoför maliyeti: €132
  • Optimize günlük van başına maliyet: €187.86/van/gün

Van başına günlük tasarruf: €56.94. 10 van için 250 çalışma günü üzerinde: €142.350/yıl, tek bir API entegrasyonundan.

Yukarıdaki ölçütler, son mil lojistik çalışmalarından yayınlanmış gerçek rakamları yansıtır. Spesifik sayılarınız coğrafya, araç türü ve durak yoğunluğuna göre değişecektir. Yoğun kentsel alanlar, naif sıralı rotalar gereksiz geri dönüşlerde en fazla mesafeyi harcadığı için en büyük kazançları görür.

Naif vs Optimize Rotalar: Görsel Karşılaştırma

Naif (sıralı) bir rota ile optimize edilmiş bir rota arasındaki fark haritada çarpıcıdır.

Naif rotalama, durağları girildiği sıraya göre beslendiğinde meydana gelir, ilk sipariş veren müşteri, coğrafyaya bakılmaksızın rotadaki ilk konumdadır. Amsterdam veya Berlin gibi bir şehirde, bu "spagetti rotası" sorununu yaratır: şoförünüz sürekli kendi yolunu kesiştirir.

Optimizasyon, durak setiniz için Gezginler Satış Adamı Problemini (TSP) çözer. 15-20 durak için bu hesapsal olarak milisaniye cinsinden yapılabilir. Yüzlerce durak içeren daha büyük filolar için, araç rotalaması sorunu (VRP) çözücüleri birden fazla araç ve kapasite sınırlarının ek kısıtlamalarını işler.

Adım 1: Teslimat Verilerinizi Yapılandırın

Her durak bir konuma ve zaman penceresine sahip teslimatlar için teslimatın ne zaman kabul edilebilir olduğunu belirten bir time_window ihtiyaç duyar.

import requests
import json

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.mapatlas.eu/v1"

# Depot (start and end point)
depot = {
    "lat": 52.3402,
    "lng": 4.8952,
    "name": "Warehouse - Sloterdijk"
}

# Delivery stops with optional time windows
stops = [
    { "lat": 52.3726, "lng": 4.8971, "name": "Albert Heijn Jordaan",
      "time_window": { "start": "09:00", "end": "12:00" } },
    { "lat": 52.3601, "lng": 4.9123, "name": "Café De Jaren",
      "time_window": { "start": "08:00", "end": "11:00" } },
    { "lat": 52.3780, "lng": 4.8801, "name": "Westergasfabriek Events",
      "time_window": { "start": "10:00", "end": "14:00" } },
    { "lat": 52.3545, "lng": 4.9041, "name": "Hotel V Nesplein",
      "time_window": None },
    { "lat": 52.3620, "lng": 4.8820, "name": "Vondelpark Paviljoen",
      "time_window": { "start": "07:00", "end": "10:00" } }
]

Adım 2: Rota Optimizasyonu Bitiş Noktasını Çağırın

Depo ve durak listesini optimize rotalama bitiş noktasına gönderin. API, durağları en verimli ziyaret sırası ile toplam rota mesafesi ve süresi ile birlikte döndürür.

def optimise_route(depot, stops, vehicle_profile="van-euro6"):
    """
    Request an optimised multi-stop route from the MapAtlas Routing API.
    vehicle_profile options: van-euro6, van-diesel-euro5, electric-van, bike
    """
    waypoints = [
        {
            "lat": s["lat"],
            "lng": s["lng"],
            "name": s["name"],
            **({"time_window": s["time_window"]} if s.get("time_window") else {})
        }
        for s in stops
    ]

    payload = {
        "origin": { "lat": depot["lat"], "lng": depot["lng"] },
        "destination": { "lat": depot["lat"], "lng": depot["lng"] },  # return to depot
        "waypoints": waypoints,
        "optimise": True,
        "vehicle_profile": vehicle_profile,
        "avoid_low_emission_zones": True  # auto-avoids LEZs for non-compliant profiles
    }

    response = requests.post(
        f"{BASE_URL}/routing/optimise",
        json=payload,
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json"
        }
    )
    response.raise_for_status()
    return response.json()

result = optimise_route(depot, stops)

Adım 3: Optimize Rotayı Ayrıştırın ve Görüntüleyin

API yanıtı, optimize sırada durağları, her durak için kümülatif ETA'ları, toplam mesafeyi ve toplam süreyi içerir.

def display_route_summary(result):
    route = result["route"]
    print(f"\n--- Optimised Route Summary ---")
    print(f"Total distance : {route['total_distance_km']:.1f} km")
    print(f"Total duration : {route['total_duration_min']:.0f} min")
    print(f"Stops          : {len(route['waypoints'])}\n")

    print(f"  START  {depot['name']}")
    for i, stop in enumerate(route["waypoints"], 1):
        eta     = stop["eta"]
        tw      = stop.get("time_window")
        on_time = "(on time)" if tw and tw["start"] <= eta <= tw["end"] else ""
        print(f"  {i:>2}.   {stop['name']:<35} ETA {eta}  {on_time}")
    print(f"  END    {depot['name']}")

    print(f"\nEstimated fuel saving vs sequential: "
          f"{result.get('saving_vs_naive_km', 0):.1f} km "
          f"({result.get('saving_pct', 0):.0f}%)")

display_route_summary(result)

Yukarıdaki beş durak için örnek çıkış:

--- Optimised Route Summary ---
Total distance : 38.4 km
Total duration : 94 min
Stops          : 5

  START  Warehouse - Sloterdijk
   1.   Vondelpark Paviljoen               ETA 07:48  (on time)
   2.   Café De Jaren                      ETA 08:31  (on time)
   3.   Albert Heijn Jordaan               ETA 09:15  (on time)
   4.   Hotel V Nesplein                   ETA 10:02
   5.   Westergasfabriek Events            ETA 10:44  (on time)
  END    Warehouse - Sloterdijk

Estimated fuel saving vs sequential: 14.2 km (27%)

Adım 4: AB Düşük Emisyon Bölgesi Kullanımı

Amsterdam'ın ZTL bölgesi, Paris'in Crit'Air sistemi ve Berlin'in Umweltzone, belirli araç türlerini belirlenen zamanlarda merkezi alanlardan kısıtlar. Mesafe açısından verimli görünen bir rota aracınız için geçersiz olabilir.

avoid_low_emission_zones: true parametresi vehicle_profile ile birleştirildiğinde, uyumlu olmayan araçlar için kısıtlı bölgeler etrafında otomatik olarak yönlendirir. Elektrikli ve Euro 6 araçları için LEZ'ler geçiş yapabilir ve parametrenin hiçbir etkisi yoktur.

# Example: diesel Euro 5 van, will be re-routed around Amsterdam ZTL
result_euro5 = optimise_route(depot, stops, vehicle_profile="van-diesel-euro5")

# Example: electric van, LEZ restrictions do not apply
result_electric = optimise_route(depot, stops, vehicle_profile="electric-van")

print(f"Euro 5 route distance  : {result_euro5['route']['total_distance_km']:.1f} km")
print(f"Electric route distance: {result_electric['route']['total_distance_km']:.1f} km")
# Electric route will typically be shorter as it can use LEZ-restricted roads

Dizel'den elektrik'e geçiş planlayan lojistik operasyonları için, rota başına bu iki çıktıyı karşılaştırmak, elektrifikasyondan mevcut aralık iyileştirmesinin doğrudan bir ölçümünü sağlar.

Adım 5: Optimize Rotayı Harita Üzerinde Görüntüleyin

API yanıtından rota geometrisini alın ve JavaScript'te bir çizgi katmanı olarak oluşturun.

import mapmetricsgl from '@mapmetrics/mapmetrics-gl';
import '@mapmetrics/mapmetrics-gl/dist/mapmetrics-gl.css';

// routeResult is the parsed API JSON response passed to the frontend
function renderOptimisedRoute(map, routeResult) {
  const { waypoints, geometry, total_distance_km, total_duration_min } = routeResult.route;

  map.on('load', () => {
    // Route line
    map.addSource('optimised-route', { type: 'geojson', data: { type: 'Feature', geometry } });
    map.addLayer({
      id: 'route-line',
      type: 'line',
      source: 'optimised-route',
      layout: { 'line-join': 'round', 'line-cap': 'round' },
      paint: { 'line-color': '#2563EB', 'line-width': 4 }
    });

    // Stop markers with sequence numbers
    waypoints.forEach((stop, i) => {
      const el = document.createElement('div');
      el.textContent = i + 1;
      el.style.cssText = `
        width:28px;height:28px;border-radius:50%;background:#2563EB;color:#fff;
        display:flex;align-items:center;justify-content:center;font-weight:700;
        font-size:13px;border:2px solid #fff;box-shadow:0 2px 6px rgba(0,0,0,0.3)
      `;

      new mapmetricsgl.Marker({ element: el })
        .setLngLat([stop.lng, stop.lat])
        .setPopup(
          new mapmetricsgl.Popup().setHTML(`
            <strong>${i + 1}. ${stop.name}</strong>
            <p>ETA: ${stop.eta}</p>
          `)
        )
        .addTo(map);
    });

    // Fit map to route bounds
    const coords = geometry.coordinates;
    const bounds = coords.reduce(
      (b, c) => b.extend(c),
      new mapmetricsgl.LngLatBounds(coords[0], coords[0])
    );
    map.fitBounds(bounds, { padding: 48 });

    // Summary panel
    document.getElementById('route-summary').innerHTML = `
      <strong>${total_distance_km.toFixed(1)} km</strong> ·
      <strong>${total_duration_min.toFixed(0)} min</strong> ·
      ${waypoints.length} stops
    `;
  });
}

const map = new mapmetricsgl.Map({
  container: 'route-map',
  style: 'https://tiles.mapatlas.eu/styles/basic/style.json?key=YOUR_API_KEY',
  center: [4.9041, 52.3676],
  zoom: 12
});

renderOptimisedRoute(map, routeResult);

Gerçek Tasarrufunuzu Hesaplamak

API yanıtı elinizde olduğunda, tasarruf hesaplaması basittir. Yanıttaki saving_vs_naive_km alanı size doğrudan tasarruf edilen mesafeyi verir. Bundan maliyet tasarruflarını türetebilirsiniz:

def calculate_savings(result, fuel_cost_per_km=0.38, driver_cost_per_hour=22.0,
                       days_per_year=250, fleet_size=10):
    saving_km    = result.get("saving_vs_naive_km", 0)
    saving_hours = saving_km / 50  # assume 50 km/h average

    daily_fuel_saving   = saving_km * fuel_cost_per_km
    daily_driver_saving = saving_hours * driver_cost_per_hour
    daily_total         = daily_fuel_saving + daily_driver_saving

    annual_fleet_saving = daily_total * days_per_year * fleet_size

    print(f"Distance saved per route : {saving_km:.1f} km")
    print(f"Time saved per route     : {saving_hours * 60:.0f} min")
    print(f"Daily saving (1 vehicle) : €{daily_total:.2f}")
    print(f"Annual saving ({fleet_size} vehicles): €{annual_fleet_saving:,.0f}")

calculate_savings(result)

Zaman Penceresi Optimizasyonu

Toplam rota mesafesini en aza indirirken saat 06:00'de bir fırına ve saat 14:00'de bir restorana teslimat yapmak kısıtlı bir optimizasyon problemidir. API bunu otomatik olarak işler, yalnızca pencereleri sağlamanız gerekir:

# Time-sensitive stops, the API will schedule these within their windows
stops_with_windows = [
    { "lat": 52.3726, "lng": 4.8971, "name": "Bakery",
      "time_window": { "start": "05:30", "end": "07:00" } },
    { "lat": 52.3620, "lng": 4.8820, "name": "Café",
      "time_window": { "start": "07:00", "end": "09:00" } },
    { "lat": 52.3545, "lng": 4.9041, "name": "Restaurant",
      "time_window": { "start": "13:00", "end": "15:00" } }
]

Depo kalkış zamanı ve mevcut trafik modeli göz önüne alındığında herhangi bir zaman penceresi kısıtlaması karşılanamıyorsa, API hangi durağa zamanında ulaşılamadığını listeleyen bir constraint_violations dizisi döndürür. Ardından gönderim yazılımınız şoförü uyarabilir veya daha erken kalkışı önerebilir.

Bunun Üstüne Inşa Etmek

Rota optimizasyonu temeli oluşturur. Çalıştığında, doğal uzantılar:

Lojistik ve Teslimat endüstri sayfası ve Filo Yönetimi endüstri sayfası, çok araçlı VRP ve depo dönüş optimizasyonu da dahil olmak üzere gönderim yazılımı ile ilgili ek MapAtlas özelliklerini kapsar.

Başlamak

Sıkça Sorulan Sorular

Rota optimizasyonu teslimat maliyetlerini nasıl azaltır?

Rota optimizasyonu, çok durak teslimat dizilerini toplam mesafe ve sürüyü en aza indirmek için yeniden sıralar. Çalışmalar, naif sıralı bir rotaya karşı mesafesel yüzde 20-35 azalış gösterir. Günde 200 km sürüşü yapan ve €0.35/km yakıt maliyetiyle bir araç için, yüzde 30 azalış araç başına günlük yaklaşık €21, araç başına yılda yaklaşık €5.000 tasarrufu sağlar.

Rota optimizasyonunda zaman pencereleri nedir?

Zaman pencereleri, bir durağın belirtilen bir zaman aralığında ziyaret edilmesini gerektiren teslimat kısıtlamalarıdır, örneğin yalnızca 09:00 ile 12:00 arasında teslimatı kabul eden bir işletme. Optimizatör, tüm zaman pencerelerine saygı duymalı ve aynı zamanda toplam rota mesafesini en aza indirmelidir, bu da kısıtlanmamış optimizasyondan önemli ölçüde daha zor bir hesaplama problemidir.

MapAtlas Routing API, AB Düşük Emisyon Bölgelerini işler mi?

Evet. MapAtlas Routing API, Amsterdam'ın ZTL, Paris Crit'Air bölgesi ve Berlin'in Umweltzone dahil olmak üzere AB Düşük Emisyon Bölgeleri için yol kısıtlama verilerini içerir. Araç profilini (dizel Euro 5, benzin, elektrik) bir parametre olarak geçirin ve yönlendirici uyumlu olmayan araçlar için otomatik olarak kısıtlı bölgelerden kaçınacaktır.

Sıkça Sorulan Sorular

Rota optimizasyonu teslimat maliyetlerini nasıl düşürür?

Rota optimizasyonu, çok duraklı teslimat sıralarını toplam mesafeyi ve sürüş süresini en aza indirecek şekilde yeniden düzenler. Araştırmalar, naif sıralı bir rotaya kıyasla gidilen mesafede tutarlı biçimde yüzde 20 ila 35 oranında azalma olduğunu göstermektedir. Günde 200 km yapan ve km başına 0,35 EUR yakıt maliyeti olan bir araç için yüzde 30'luk bir azalma, araç başına günde yaklaşık 21 EUR tasarruf sağlar; bu da araç başına yılda yaklaşık 5.000 EUR demektir.

Rota optimizasyonunda zaman pencereleri nedir?

Zaman pencereleri, bir durağın belirli bir zaman aralığında ziyaret edilmesini zorunlu kılan teslimat kısıtlamalarıdır; örneğin yalnızca 09:00 ile 12:00 arasında teslimat kabul eden bir işletme gibi. Optimizer, tüm zaman pencerelerini karşılarken toplam rota mesafesini de minimize etmelidir; bu, kısıtsız optimizasyona kıyasla çok daha zorlu bir hesaplama problemidir.

MapAtlas Routing API, AB Düşük Emisyon Bölgelerini yönetir mi?

Evet. MapAtlas Routing API, Amsterdam'ın ZTL'si, Paris'in Crit'Air bölgesi ve Berlin'in Umweltzone'u dahil olmak üzere AB Düşük Emisyon Bölgeleri (LEZ) için yol kısıtlama verilerini içerir. Araç profilini (dizel Euro 5, benzin, elektrikli) parametre olarak girin; router uyumsuz araçlar için kısıtlı bölgeleri otomatik olarak atlayacaktır.

Faydalı buldunuz mu? Paylaşın.

Yazar hakkında

Brent van der Heiden

Yazan

Brent van der Heiden

Co-Founder & CEO at MapAtlas

Brent built MapAtlas out of a conviction that developers deserve location APIs with fair pricing and genuine end-user privacy. He writes about geospatial infrastructure, AI search visibility, and how location data powers the products people rely on every day.

Tüm makaleleri görüntüle
Bloga dön