简体   繁体   English

给定第一个点和距离,如何计算第二个点的纬度/经度?

[英]How to calculate the lat/lng of a 2nd point given 1st point and distance?

I still have issues in calculating the lat/lng for 2nd point provided and lat/lng for 1nd point and distance. 在计算提供的第二个点的经度/经度和计算第一点和距离的经度/经度时,我仍然遇到问题。

i found one solution here in Javascript, I tried to convert to Java. 我在Javascript中找到了一个解决方案,我试图转换为Java。 but the result was not accurate, it seems I've done something wrong. 但结果不准确,看来我做错了。

How to calculate the latlng of a point a certain distance away from another? 如何计算一个点与另一个点有一定距离的纬度?

public class Misc {





        double EARTH_RADIUS_METERS= 6378.1 *1024;

        private double toRad(double value) {
           return  value*  (Math.PI/ 180);
        }

        private double toDeg (double value) {
           return value*  (180 / Math.PI);
        }


        /*-------------------------------------------------------------------------
         * Given a starting lat/lon point on earth, distance (in meters)
         * and bearing, calculates destination coordinates lat2/lon2.
         *
         * all params in radians
         *-------------------------------------------------------------------------*/
         GPoint destCoordsInRadians(double lat1, double lon1, 
                                 double distanceMeters, double bearing
                                 /*,double* lat2, double* lon2*/)
        {
            //-------------------------------------------------------------------------
            // Algorithm from http://www.geomidpoint.com/destination/calculation.html
            // Algorithm also at http://www.movable-type.co.uk/scripts/latlong.html
            //
            // Spherical Earth Model
            //   1. Let radiusEarth = 6372.7976 km or radiusEarth=3959.8728 miles
            //   2. Convert distance to the distance in radians.
            //      dist = dist/radiusEarth
            //   3. Calculate the destination coordinates.
            //      lat2 = asin(sin(lat1)*cos(dist) + cos(lat1)*sin(dist)*cos(brg))
            //      lon2 = lon1 + atan2(sin(brg)*sin(dist)*cos(lat1), cos(dist)-sin(lat1)*sin(lat2))
            //-------------------------------------------------------------------------
            double distRadians = distanceMeters / EARTH_RADIUS_METERS;

            double lat2 = Math.asin( Math.sin(lat1) * Math.cos(distRadians) + Math.cos(lat1) * Math.sin(distRadians) * Math.cos(bearing));

            double  lon2 = lon1 + Math.atan2( Math.sin(bearing) * Math.sin(distRadians) * Math.cos(lat1), 
                    Math.cos(distRadians) - Math.sin(lat1) * Math.sin(lat2) );  

            return new  GPoint( lat2  , lon2 );

        }

        /*-------------------------------------------------------------------------
         * Given a starting lat/lon point on earth, distance (in meters)
         * and bearing, calculates destination coordinates lat2/lon2.
         *
         * all params in degrees
         *-------------------------------------------------------------------------*/
         GPoint destCoordsInDegrees(double lat1, double lon1, 
                                 double distanceMeters, double bearing/*,
                                 double* lat2, double* lon2*/)
        {
            GPoint gPoint2=destCoordsInRadians(/*Deg_to_*/toRad(lat1), /*Deg_to_*/toRad(lon1),
                                distanceMeters, /*Deg_to_*/toRad(bearing)/*,
                                lat2, lon2*/);

            gPoint2.lat = /*Rad_to_*/toDeg( gPoint2.lat );
            gPoint2.lon = normalize180( /*Rad_to_*/toDeg( gPoint2.lon )) ;

            return gPoint2;
        }


        /*-------------------------------------------------------------------------
         * Given two lat/lon points on earth, calculates the heading
         * from lat1/lon1 to lat2/lon2.  
         * 
         * lat/lon params in radians
         * result in radians
         *-------------------------------------------------------------------------*/
        double headingInRadians(double lat1, double lon1, double lat2, double lon2)
        {
            //-------------------------------------------------------------------------
            // Algorithm found at http://www.movable-type.co.uk/scripts/latlong.html
            //
            // Spherical Law of Cosines
            //
            // Formula: ? = atan2(  sin(?lon) * cos(lat2),
            //                      cos(lat1) * sin(lat2) ? sin(lat1) * cos(lat2) * cos(?lon) )
            // JavaScript:  
            //  
            //  var y = Math.sin(dLon) * Math.cos(lat2);
            //  var x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
            //  var brng = Math.atan2(y, x).toDeg();
            //-------------------------------------------------------------------------
            double dLon = lon2 - lon1;
            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);

            return Math.atan2(y, x);
        }

        /*-------------------------------------------------------------------------
         * Given two lat/lon points on earth, calculates the heading
         * from lat1/lon1 to lat2/lon2.  
         * 
         * lat/lon params in degrees
         * result in degrees
         *-------------------------------------------------------------------------*/
        double headingInDegrees(double lat1, double lon1, double lat2, double lon2)
        {
            return /*Rad_to_*/toDeg( headingInRadians(/*Deg_to_*/toRad(lat1), 
                    /*Deg_to_*/toRad(lon1), 
                    /*Deg_to_*/toRad(lat2),
                    /*Deg_to_*/toRad(lon2)) );
        }

        // Normalize a heading in degrees to be within -179.999999° to 180.00000°
        double normalize180(double heading)
        {
            while (true) {
                if (heading <= -180) {
                    heading += 360;
                } else if (heading > 180) {
                    heading -= 360;
                } else {
                    return heading;
                }
            }
        }

        // Normalize a heading in degrees to be within -179.999999° to 180.00000°
        float normalize180f(float heading)
        {
            while (true) {
                if (heading <= -180) {
                    heading += 360;
                } else if (heading > 180) {
                    heading -= 360;
                } else {
                    return heading;
                }
            }
        }

        // Normalize a heading in degrees to be within 0° to 359.999999°
        double normalize360(double heading)
        {
            while (true) {
                if (heading < 0) {
                    heading += 360;
                } else if (heading >= 360) {
                    heading -= 360;
                } else {
                    return heading;
                }
            }
        }

        // Normalize a heading in degrees to be within 0° to 359.999999°
        float normalize360f(float heading)
        {
            while (true) {
                if (heading < 0) {
                    heading += 360;
                } else if (heading >= 360) {
                    heading -= 360;
                } else {
                    return heading;
                }
            }
        }

}

You need one more parameter, namely "bearing". 您还需要一个参数,即“ bearing”。 Then: 然后:

var d = radius/6378800; // 6378800 is Earth radius in meters
var lat1 = (PI/180)* centerLat;
var lng1 = (PI/180)* centerLng;

// Go around a circle from 0 to 360 degrees, every 10 degrees or set a to your desired bearing, in degrees.
for (var a = 0 ; a < 361 ; a+=10 ) {
    var tc = (PI/180)*a;
    var y = asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc));
    var dlng = atan2(sin(tc)*sin(d)*cos(lat1),cos(d)-sin(lat1)*sin(y));
    var x = ((lng1-dlng+PI) % (2*PI)) - PI ;
    var lat = y*(180/PI);
    var lon = x*(180/PI);

    // Convert the lat and lon to pixel, if needed. (x,y) 
}

Originally from this other SO thread: How to change 1 meter to pixel distance? 最初是从另一个SO线程: 如何将1米更改为像素距离?

here is great answer for this question: 是这个问题的好答案:

you can use android-maps-utils with method: 您可以将android-maps-utils与方法配合使用:

SphericalUtil.computeOffset(latLng, dist, brng)

in case you want to do it by your own: 如果您想自己做:

private LatLng getDestinationPoint(LatLng source, double brng, double dist) {
        dist = dist / 6371;
        brng = Math.toRadians(brng);

        double lat1 = Math.toRadians(source.latitude), lon1 = Math.toRadians(source.longitude);
        double lat2 = Math.asin(Math.sin(lat1) * Math.cos(dist) +
                                Math.cos(lat1) * Math.sin(dist) * Math.cos(brng));
        double lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(dist) *
                                        Math.cos(lat1),
                                        Math.cos(dist) - Math.sin(lat1) *
                                        Math.sin(lat2));
        if (Double.isNaN(lat2) || Double.isNaN(lon2)) {
            return null;
        }
        return new LatLng(Math.toDegrees(lat2), Math.toDegrees(lon2));
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM