Calculate angle between two Latitude/Longitude points

后端 未结 17 1372
故里飘歌
故里飘歌 2020-12-07 17:51

Is there a way to calculate angle between two Latitude/Longitude points?

What I am trying to achieve is to know where the user is heading. For example, user is head

相关标签:
17条回答
  • 2020-12-07 18:34

    In The Javascript, I create a function name angleFromCoordinate in which i pass two lat/lng. This function will return angel between that two lat/lng

    function angleFromCoordinate(lat1,lon1,lat2,lon2) {
        var p1 = {
            x: lat1,
            y: lon1
        };
    
        var p2 = {
            x: lat2,
            y: lon2
        };
        // angle in radians
        var angleRadians = Math.atan2(p2.y - p1.y, p2.x - p1.x);
        // angle in degrees
        var angleDeg = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;
        console.log(angleDeg);
        return angleDeg;
    }
    

    Working Code Snippet

    function angleFromCoordinate(lat1,lon1,lat2,lon2) {
        var p1 = {
            x: lat1,
            y: lon1
        };
    
        var p2 = {
            x: lat2,
            y: lon2
        };
        // angle in radians
        var angleRadians = Math.atan2(p2.y - p1.y, p2.x - p1.x);
        // angle in degrees
        var angleDeg = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;
    
        document.getElementById('rotation').innerHTML ="Rotation : "+ angleDeg;
        return angleDeg;
        
    }
         angleFromCoordinate(37.330604,-122.028947,37.3322109,-122.0329665);
    <html>
    <p id="rotation">Rotation : </p>
    </html>

    0 讨论(0)
  • 2020-12-07 18:37
    function calculateAngle(lat, lng) {
        var checkLengthInterval = 2;
    
        // Calculate Angle
        //If ObjFeed == [] add first object.
        if (ObjFeed.length == 0) {
            ObjFeed.push({ 'lat': lat, 'lng': lng });
        } else {
            // Get last object from list to calculate angle betwn last and latest.
            var tempNode = ObjFeed[ObjFeed.length - 1];
            // If last lat and lng is same as current it will always return 0 angle.so only push lat lng in obj which is diff than last one.
            if (!(tempNode.lat == lat && tempNode.lng == lng)) {
                ObjFeed.push({ 'lat': lat, 'lng': lng });
            } else {
                console.log('exact match for lat lng');
            }
        }
         // this is for to keep only few objects in the list and remove other
        if (ObjFeed.length >= checkLengthInterval) {
            // calculating angle only if previous data point is available
            ObjFeed = ObjFeed.slice(-1 * checkLengthInterval); // remove all items in array except last two
            var point1 = ObjFeed[ObjFeed.length - checkLengthInterval];
            var point2 = ObjFeed[ObjFeed.length - 1];
    
            console.log('previous point1', point1);
            console.log('next point2', point2);
    
            var dLng = (point2.lng - point1.lng);
            var dLat = (point2.lat - point1.lat);
    
            dLng = dLng * 10000;
            dLat = dLat * 10000;
    
            var dlat_by_dlan = 0;
    
            try {
                dlat_by_dlan = dLng / dLat;
            } catch (err) {
                dlat_by_dlan = NaN;
                console.log('Exception: dLat == 0');
            }
    
            var angleDegreeBearing = 0, angleBearingRad = 0;
            angleBearingRad = Math.atan(dlat_by_dlan);
            angleDegreeBearing = angleBearingRad * 180 / Math.PI;
    
            if (dLat < 0 && dLng < 0) {
                angleDegreeBearing = angleDegreeBearing + 180;
            } else if (dLat < 0 && dLng > 0) {
                angleDegreeBearing = angleDegreeBearing + 180;
            } else if (dLat == 0 && dLng == 0) {
                angleDegreeBearing = prevVechicleAngle;
            } else if (dlat_by_dlan == NaN) {
                angleDegreeBearing = prevVechicleAngle;
            }
    
            console.log('angleDegreeBearing', angleDegreeBearing);
    
        } else {
            // setting up default angle to 0 if previous data point is not available to calculate actual anglle
            console.log('feedArray default angle 0');
            angleDegreeBearing = 0;
        }
        prevVechicleAngle = angleDegreeBearing;
        return angleDegreeBearing;
    
    }
    
    0 讨论(0)
  • 2020-12-07 18:38

    using this referance to calculate Angle:

    private double angleFromCoordinate(double lat1, double long1, double lat2,
            double long2) {
    
        double dLon = (long2 - long1);
    
        double y = Math.sin(dLon) * Math.cos(lat2);
        double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1)
                * Math.cos(lat2) * Math.cos(dLon);
    
        double brng = Math.atan2(y, x);
    
        brng = Math.toDegrees(brng);
        brng = (brng + 360) % 360;
        brng = 360 - brng; // count degrees counter-clockwise - remove to make clockwise
    
        return brng;
    }
    
    0 讨论(0)
  • 2020-12-07 18:38

    For those who use C/C++, below is the tested code:

    static const auto PI = 3.14159265358979323846, diameterOfEarthMeters = 6371.0 * 2 * 1000;
    
    double degreeToRadian (double degree) { return (degree * PI / 180); };
    double radianToDegree (double radian) { return (radian * 180 / PI); };
    
    double CoordinatesToAngle (const double latitude1,
                               const double longitude1,
                               const double latitude2,
                               const double longitude2)
    {
      const auto longitudeDifferenceRadians = degreeToRadian(longitude2 - longitude1);
      auto latitude1Radian = degreeToRadian(latitude1),
           latitude2Radian = degreeToRadian(latitude2);
    
      const auto x = std::cos(latitude1Radian) * std::sin(latitude2Radian) -
                     std::sin(latitude1Radian) * std::cos(latitude2Radian) *
                     std::cos(longitudeDifferenceRadians);
      const auto y = std::sin(longitudeDifferenceRadians) * std::cos(latitude2Radian);
    
      return radianToDegree(std::atan2(y, x));
    }
    
    double CoordinatesToMeters (const double latitude1,
                                const double longitude1,
                                const double latitude2,
                                const double longitude2)
    {
      auto latitude1Radian = degreeToRadian(latitude1),
           longitude1Radian = degreeToRadian(longitude1),
           latitude2Radian = degreeToRadian(latitude2),
           longitude2Radian = degreeToRadian(longitude2);
      auto x = std::sin((latitude2Radian - latitude1Radian) / 2),
           y = std::sin((longitude2Radian - longitude1Radian) / 2);
    
      return diameterOfEarthMeters *
             std::asin(std::sqrt((x * x) +
                                 (std::cos(latitude1Radian) * std::cos(latitude2Radian) * y * y)));
    }
    
    0 讨论(0)
  • 2020-12-07 18:38

    Make sure its a rhumb line bearing NOT a great circle bearing as the initial bearing changes according to distance

     double angle= Math.min((pbearingf-tbearingf) < 0 ? pbearingf-tbearingf+360:pbearingf-tbearingf, (tbearingf-pbearingf)<0?tbearingf-pbearingf+360:tbearingf-pbearingf);
    
    0 讨论(0)
提交回复
热议问题