Skip to main content
Teslimat ve Araç Paylaşımı için Canlı Sürücü Takip Haritası Yapımı
Tutorials

Teslimat ve Araç Paylaşımı için Canlı Sürücü Takip Haritası Yapımı

WebSocket GPS güncellemeleri, akıcı işaretçi interpolasyonu, rota gösterimi ve ETA hesaplamasıyla MapAtlas Maps ve Routing API'leri üzerinde canlı takip haritası kurun.

Brent van der Heiden8 min read
#live tracking map#driver tracking#real-time map#websocket map#delivery tracking#rideshare app

Takip haritası, yemek teslimatı ve araç paylaşımı uygulamalarında kullanıcıların en çok baktığı ekrandır. Müşteriler beklerken gözlerini bu ekrandan ayırmaz. Akıcı hareket, doğru ETA ve net bir rota çizgisi, profesyonel görünen bir uygulamayı güven vermeyen bir uygulamadan ayırır.

Bu eğitimde müşteriye gösterilen takip haritasını sıfırdan kuruyoruz: GPS konumlarını WebSocket üzerinden yayınlayan bir backend, bu konumları alıp sürücü işaretçisini zıplatmadan hareket ettiren bir frontend, MapAtlas Routing API ile çizilen bir rota ve canlı bir ETA göstergesi. Uygulamanın tamamı 70 satırdan kısa istemci tarafı JavaScript'ten oluşuyor ve WebSocket mesajı gönderebilen her backend ile çalışacak şekilde tasarlandı.

Bu mimari yemek teslimatı, market alışverişi, araç paylaşımı, saha hizmetleri ve bir aracın sabit bir hedefe ilerlediği, müşterinin de bunu gerçek zamanlı izlediği her senaryo için uygundur.

Mimariye genel bakış

Kod yazmadan önce veri akışını anlamak işinizi kolaylaştırır:

  1. Sürücü uygulaması (mobil cihaz, GPS donanımı) enlem ve boylam bilgisini her 3 ile 5 saniyede bir backend'inize gönderir.
  2. Backend (Node.js, Python, Go, tercih sizin) bilinen son konumu saklar ve WebSocket üzerinden siparişe abone olan tüm istemcilere yayınlar.
  3. Müşteri tarayıcısı WebSocket mesajlarını alır ve haritadaki işaretçiyi interpolasyonlu animasyonla hareket ettirir.
  4. Routing API, sipariş oluşturulduğunda planlanan rotayı almak için bir kez çağrılır. Çözülen polyline bir çizgi katmanı olarak gösterilir.
  5. ETA, kalan mesafe ortalama hızla karşılaştırılarak ya da Routing API sürücünün mevcut konumundan yeniden çağrılarak güncellenir.

Backend uygulaması bu eğitimin kapsamı dışında. Ancak mesajları aşağıdaki biçimde gönderen her WebSocket sunucusu, bu yazıdaki frontend koduyla çalışır:

{
  "type": "position_update",
  "orderId": "order-8821",
  "lat": 52.3741,
  "lng": 4.8952,
  "heading": 92,
  "speed": 28,
  "timestamp": 1738234521000
}

Adım 1: Haritayı başlatın

Haritayı teslimatın başlangıç noktasına ortalanmış şekilde kurun. Routing API çağrısı 4. adımda yapılacak, bu yüzden şimdilik yalnızca harita alanını başlatın.

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

const map = new mapmetricsgl.Map({
  container: 'tracking-map',
  style: 'https://gateway.mapmetrics-atlas.net/styles/?fileName=YOUR_STYLE_ID/style.json&token=YOUR_API_KEY',
  center: [4.9041, 52.3676],
  zoom: 14
});

// Hedef işaretçisi (restoran veya teslim alma noktası)
const destination = [4.9001, 52.3791];

new mapmetricsgl.Marker({ color: '#EF4444' })
  .setLngLat(destination)
  .setPopup(new mapmetricsgl.Popup().setHTML('<strong>Pickup point</strong>'))
  .addTo(map);

Adım 2: Yöne göre dönen sürücü işaretçisi

Sürücü işaretçisini ayrı oluşturun, böylece her GPS sinyalinde konumunu güncelleyebilirsiniz. Özel bir HTML öğesi, işaretçi simgesini sürücünün gidiş yönüne göre döndürmenizi sağlar. Bu küçük ayrıntı takibi çok daha gerçekçi gösterir.

// Döndürebilmek için özel öğe
const driverEl = document.createElement('div');
driverEl.innerHTML = '🚗';
driverEl.style.cssText = 'font-size:28px;transform-origin:center;transition:transform 0.3s';

const driverMarker = new mapmetricsgl.Marker({ element: driverEl, anchor: 'center' })
  .setLngLat([4.9041, 52.3676])
  .addTo(map);

function setDriverHeading(heading) {
  driverEl.style.transform = `rotate(${heading}deg)`;
}

Adım 3: WebSocket bağlantısı ve akıcı interpolasyon

Takip haritasının özü bu adımda. WebSocket'e bağlanmak tek satır sürüyor. Asıl önemli kısım, işaretçinin konumunu GPS sinyalleri arasında interpolasyonla hesaplamak. Böylece işaretçi bir noktadan diğerine ışınlanmak yerine akıcı biçimde kayar.

let prevPos  = null; // { lat, lng }
let animFrame = null;

function interpolateMarker(fromLat, fromLng, toLat, toLng, durationMs) {
  const startTime = performance.now();

  function step(now) {
    const elapsed = now - startTime;
    const t = Math.min(elapsed / durationMs, 1); // 0 → 1

    const lat = fromLat + (toLat - fromLat) * t;
    const lng = fromLng + (toLng - fromLng) * t;

    driverMarker.setLngLat([lng, lat]);

    if (t < 1) {
      animFrame = requestAnimationFrame(step);
    }
  }

  if (animFrame) cancelAnimationFrame(animFrame);
  animFrame = requestAnimationFrame(step);
}

const ws = new WebSocket('wss://your-backend.example.com/track/order-8821');

ws.addEventListener('message', (event) => {
  const msg = JSON.parse(event.data);
  if (msg.type !== 'position_update') return;

  const { lat, lng, heading } = msg;

  if (prevPos) {
    // Önceki konumdan yeni konuma akıcı animasyon
    interpolateMarker(prevPos.lat, prevPos.lng, lat, lng, 400);
  } else {
    // İlk sinyal, işaretçiyi hemen yerleştir
    driverMarker.setLngLat([lng, lat]);
    map.flyTo({ center: [lng, lat], zoom: 15 });
  }

  setDriverHeading(heading);
  updateETA(lat, lng);
  prevPos = { lat, lng };
});

ws.addEventListener('close', () => {
  console.log('Driver has arrived or connection closed.');
});

400 ms'lik interpolasyon süresi, 3 ile 5 saniyelik tipik GPS sinyal aralığıyla oldukça iyi uyum sağlar. İşaretçi gerçek konumun her zaman biraz gerisinde kalır, ancak gözle fark edilir bir sıçrama yapmaz.

Adım 4: Routing API ile planlanan rotayı çizin

Sipariş atandığında rotanın tamamını alın. Polyline koordinatlarını saklayın ve bir GeoJSON çizgi katmanı olarak çizin. Çok duraklı senaryolar Route Optimization API eğitiminde anlatılıyor. A noktasından B noktasına basit bir teslimat için istek oldukça sade:

async function fetchAndDrawRoute(originLat, originLng, destLat, destLng) {
  const url = new URL('https://gateway.mapmetrics-atlas.net/directions/');
  url.searchParams.set('token', 'YOUR_API_KEY');

  const res  = await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      locations: [
        { lat: originLat, lon: originLng },
        { lat: destLat, lon: destLng },
      ],
      costing: 'auto',
      format: 'osrm',
      shape_format: 'geojson',
    }),
  });
  const data = await res.json();

  if (!data.routes?.length) return;

  const route = data.routes[0];

  map.on('load', () => {
    map.addSource('route', {
      type: 'geojson',
      data: {
        type: 'Feature',
        geometry: route.geometry // GeoJSON LineString
      }
    });

    map.addLayer({
      id: 'route-line',
      type: 'line',
      source: 'route',
      layout: { 'line-join': 'round', 'line-cap': 'round' },
      paint: {
        'line-color': '#3B82F6',
        'line-width': 4,
        'line-opacity': 0.8
      }
    });
  });

  return route.duration; // saniye
}

Adım 5: ETA'yı hesaplayın ve gösterin

ETA'yı, sürücünün mevcut konumunu hedefle karşılaştırarak hesaplayın. Daha yüksek doğruluk için Routing API'yi her 30 saniyede bir sürücünün mevcut konumundan yeniden çağırın ve güncel bir yolculuk süresi tahmini alın.

function haversineKm(lat1, lon1, lat2, lon2) {
  const R = 6371;
  const dLat = ((lat2 - lat1) * Math.PI) / 180;
  const dLon = ((lon2 - lon1) * Math.PI) / 180;
  const a = Math.sin(dLat / 2) ** 2 +
    Math.cos((lat1 * Math.PI) / 180) *
    Math.cos((lat2 * Math.PI) / 180) *
    Math.sin(dLon / 2) ** 2;
  return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
}

let lastRouteFetch = 0;

async function updateETA(driverLat, driverLng) {
  const [destLng, destLat] = destination;
  const distKm = haversineKm(driverLat, driverLng, destLat, destLng);

  // Hızlı istemci tarafı tahmini (şehir içi ortalama 30 km/sa varsayımı)
  const minutesEstimate = Math.ceil((distKm / 30) * 60);
  document.getElementById('eta').textContent =
    distKm < 0.1
      ? 'Arriving now'
      : `ETA: ${minutesEstimate} min (${distKm.toFixed(1)} km)`;

  // Doğruluk için Routing API'den her 30 saniyede bir yeniden al
  const now = Date.now();
  if (now - lastRouteFetch > 30_000) {
    lastRouteFetch = now;
    const url = new URL('https://gateway.mapmetrics-atlas.net/directions/');
    url.searchParams.set('token', 'YOUR_API_KEY');

    const res  = await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        locations: [
          { lat: driverLat, lon: driverLng },
          { lat: destLat, lon: destLng },
        ],
        costing: 'auto',
        format: 'osrm',
        shape_format: 'geojson',
      }),
    });
    const data = await res.json();
    if (data.routes?.length) {
      const mins = Math.ceil(data.routes[0].duration / 60);
      document.getElementById('eta').textContent = `ETA: ${mins} min`;
    }
  }
}

Sürücü takibinde GDPR'a dikkat edilmesi gerekenler

Sürücünün GPS koordinatları, GDPR Madde 4(1) kapsamında kişisel veridir. Burada geçerli olan GDPR ilkeleri, Madde 5'teki veri minimizasyonu ve saklama süresinin sınırlandırılması ilkeleridir:

Veri minimizasyonu: Yalnızca sevkiyat için gereken alanları takip edin: konum, yön, hız. Operasyonel olarak gerekenin ötesinde ham GPS geçmişi kaydetmeyin.

Saklama süresi sınırları: Ayrıntılı yolculuk takip verileri, sipariş tamamlandığında silinmeli ya da geri döndürülemez biçimde anonimleştirilmelidir. Tek bir sürücüyle ilişkilendirilmeyen toplu rota verileri, ağ optimizasyonu için daha uzun süre saklanabilir.

Hukuki dayanak: Belgelenmiş bir denge testiyle desteklenen Madde 6(1)(f) kapsamındaki meşru menfaat ya da Madde 6(1)(b) kapsamındaki sözleşmenin ifası, gerçek zamanlı sevkiyat takibini genellikle kapsar. Takip verilerini ikincil amaçlarla (analiz, kıyaslama) kullanacaksanız ayrı bir dayanağı belgelemeniz gerekir.

Sürücülere şeffaflık: Sürücülerin işe alım sürecine takiple ilgili açık bir bilgilendirme ekleyin. Sürücülere hangi verilerin toplandığı, ne kadar süre saklandığı ve kimlerin erişebildiği söylenmelidir.

Veri konumu: MapAtlas tüm API isteklerini AB içinde işler. Bu, ABD merkezli harita sağlayıcılarında ortaya çıkan üçüncü ülkeye veri aktarımı sorununu ortadan kaldırır. Uyumluluğun tüm resmi için GDPR uyumlu harita API'leri için AB geliştirici rehberine bakın.

Özellikle araç paylaşımı ve mobilite sektörü senaryosu için MapAtlas, DPA belgelerini ve AB sunucu garantilerini standart olarak sunar. Lojistik ve teslimat sektör sayfası ise filo ve çok sürücülü senaryoları ele alıyor.

Canlı ortama hazırlık

Takip özelliğini müşterilere sunmadan önce şu maddeleri kontrol edin:

  • WebSocket yeniden bağlantısı: Üstel geri çekilme (exponential backoff) ile ws.addEventListener('close', reconnect) ekleyin. Mobil ağlarda bağlantılar sık kopar.
  • Eskimiş konumların yönetimi: 15 saniye boyunca güncelleme gelmezse son konumu ekranda bırakmak yerine "sürücü konumu aranıyor" durumunu gösterin.
  • Varış tespiti: distKm < 0.1 olduğunda "vardı" durumunu tetikleyin, WebSocket'i kapatın ve bir onay ekranı gösterin.
  • Kamera sürücüyü takip etsin: Sürücüyü ortada tutmak için her konum güncellemesinde map.panTo([lng, lat]) çağırın. Haritayı kendileri gezmek isteyen kullanıcılar için takip modunu kapatan bir "kilit" düğmesi ekleyin.

Sonraki adımlar

Sıkça sorulan sorular

Sürücünün konumunu haritada akıcı biçimde nasıl hareket ettiririm?

GPS sinyalleri birkaç saniyede bir gelir. İşaretçinin konumunu doğrudan güncellerseniz gözle görülür sıçramalar oluşur. Akıcı interpolasyon, requestAnimationFrame ile işaretçiyi küçük adımlarla ilerleterek önceki konumdan yenisine kısa bir sürede (300 ile 500 ms) taşır. Böylece GPS güncellemeleri seyrek olsa bile hareket kesintisiz görünür.

Sürücü konum verileri GDPR kapsamında mı?

Evet. Sürücünün gerçek zamanlı GPS koordinatları GDPR Madde 4 kapsamında kişisel veridir. Platformlar takip verilerini yalnızca gerektiği kadar saklamalıdır; yolculuk tamamlandığında bu verileri silmek ya da anonimleştirmek en güvenli varsayılan yaklaşımdır. Bu verilerin işlenmesi hukuki bir dayanak gerektirir ve sürücünün gizlilik bildiriminde açıklanmalıdır.

Planlanan rotayı takip haritasında göstermek için MapAtlas Routing API'yi kullanabilir miyim?

Evet. Yolculuk oluşturulduğunda rotayı Routing API'den alın, polyline'ı çözün ve haritaya GeoJSON çizgi katmanı olarak ekleyin. Sürücü ilerledikçe, ETA'yı dinamik olarak yeniden hesaplamak için rotayı isterseniz mevcut konumdan tekrar alabilirsiniz.

Sıkça Sorulan Sorular

Sürücünün konumunu haritada akıcı biçimde nasıl hareket ettiririm?

GPS sinyalleri birkaç saniyede bir gelir. İşaretçinin konumunu doğrudan güncellerseniz gözle görülür sıçramalar oluşur. Akıcı interpolasyon, `requestAnimationFrame` ile işaretçiyi küçük adımlarla ilerleterek önceki konumdan yenisine kısa bir sürede (300 ile 500 ms) taşır. Böylece GPS güncellemeleri seyrek olsa bile hareket kesintisiz görünür.

Sürücü konum verileri GDPR kapsamında mı?

Evet. Sürücünün gerçek zamanlı GPS koordinatları GDPR Madde 4 kapsamında kişisel veridir. Platformlar takip verilerini yalnızca gerektiği kadar saklamalıdır; yolculuk tamamlandığında bu verileri silmek ya da anonimleştirmek en güvenli varsayılan yaklaşımdır. Bu verilerin işlenmesi hukuki bir dayanak gerektirir ve sürücünün gizlilik bildiriminde açıklanmalıdır.

Planlanan rotayı takip haritasında göstermek için MapAtlas Routing API'yi kullanabilir miyim?

Evet. Yolculuk oluşturulduğunda rotayı Routing API'den alın, polyline'ı çözün ve haritaya GeoJSON çizgi katmanı olarak ekleyin. Sürücü ilerledikçe, ETA'yı dinamik olarak yeniden hesaplamak için rotayı isterseniz mevcut konumdan tekrar alabilirsiniz.

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. Before that he co-founded MapMetrics, a community mapping and navigation app. He writes about geospatial infrastructure, map data, 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