0

The following code would allow for tracking and giving the speed of a user.

I'd like to have this info, and even average speed, but I receive this error:

"166:37 Uncaught TypeError: previousLatLng.distanceTo is not a function"

This is strange because the function is called with let. I'm using Leaflet plugin leaflet-control-geocoder and turf.js library.

This was previously discussed at https://stackoverflow.com/questions/72071582/how-can-i-compute-current-speed-average-speed-and-total-distance-with-leafletjs/72073783?noredirect=1#comment129498674_72073783 where "Leaflet provides a useful latlngA.distanceTo(latlngB) method to convert a pair of GPS coordinates into actual distance"

I made a jsfiddle: https://jsfiddle.net/vincedchart/01f8rjzb/1/

      const exportButton = document.getElementById("export");
      let intv;

      const status = document.getElementById("status");

      var map = L.map("map", {
        center: [9.082, 8.6753],
        zoom: 8,
      });
      var osm = L.tileLayer(
        "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
        {
          attribution:
                                '&copy; <a href="https://skatespot.com">SkateSpot, Inc.</a>',
        }
      ).addTo(map);
      L.Control.geocoder().addTo(map);
      if (!navigator.geolocation) {
        console.log("Your browser doesn't support geolocation feature!");
      }

      const trackingPath = [];
      const polyline = L.polyline([], {
        color: "red",
        weight: 3,
        className: "path",
      }).addTo(map);

      function start() {
        navigator.geolocation.getCurrentPosition(getPosition);
        intv = setInterval(() => {
          navigator.geolocation.getCurrentPosition(getPosition);
        }, 1000);
      }

   
   let totalElapsedTime = 0;
let totalDistance = 0;
let previousTime;
let previousLatLng;

function getPosition(position) {
  const time = new Date();
  const latLng = L.latLng(
    position.latitude,
    position.longitude
  );

  // Skip first point (no computation is possible)
  if (previousTime && previousLatLng) {
    const elapsedTime = (time.getTime() - previousTime.getTime()) / 1000; // In seconds
    const distance = previousLatLng.distanceTo(latLng);

    const currentSpeed = distance / elapsedTime; // In meters / second

    totalElapsedTime += elapsedTime;
    totalDistance += distance;

    const averageSpeed = totalDistance / totalElapsedTime; // In meters / second
  }

  // Record time and position for next computation
  previousTime = time;
  previousLatLng = position;

  // Graphic stuff...
}

  

      function startTracking(e) {
        status.innerText = "Started tracking...";
        e.preventDefault();
        start();
      }

      function stopTracking(e) {
        status.innerText = "Stopped tracking.";
        e.preventDefault();
        clearInterval(intv);
      }

      document.getElementById("start").addEventListener("click", startTracking);
      document.getElementById("stop").addEventListener("click", stopTracking);
      document.getElementById("marker").addEventListener("click", addMarker);
    </script>
8
  • @TomazicM hello, ok it's done (added the js and css links, I don't see anything else)
    – Vincent Dc
    Aug 12 at 18:57
  • What is .distanceTo supposed to be? Where does it come from? navigatotor.geolocation position has only coords and timestamp properties, no methods.
    – TomazicM
    Aug 12 at 20:22
  • 1
    But .distanceTo is valid only for L.latLng coordinates. position coordinate is created by browser, not by Leaflet, so it does not have that method.
    – TomazicM
    Aug 12 at 20:58
  • 2
    previousLatLng is not an instance of L.LatLng. Pay attention to previousLatLng = position;. Aug 12 at 20:58
  • 1
    All you have to do is to replace statement previousLatLng = position; with previousLatLng = latLng;
    – TomazicM
    Aug 14 at 18:40

1 Answer 1

0

Replace

previousLatLng = position;

with

previousLatLng = latLng

and

const latLng = L.latLng( position.latitude, position.longitude ); 

by

const latLng = L.latLng( latitude, longitude );

and all this, inside the function getPosition(position) : convert speed to kph without decimals :

const currentSpeedkmh = currentSpeed * 3.6;
      const currentSpeedready = Math.trunc ( currentSpeedkmh );

and

  const averageSpeedkmh = averageSpeed * 3.6;
  const averageSpeedready = Math.trunc( averageSpeedkmh );

get the status updated:

                const vit = [currentSpeedready, averageSpeedready];
          status.innerText = `Current and average speed ${vit.join(", ")}`;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.