使用 Google Map API V2 查找地图上两点之间的距离

Posted

技术标签:

【中文标题】使用 Google Map API V2 查找地图上两点之间的距离【英文标题】:Find distance between two points on map using Google Map API V2 【发布时间】:2013-01-01 21:27:54 【问题描述】:

我在我的 android 应用程序中使用 google map api v2,我能够显示地图并在其上放置标记,但现在我遇到了需要找出两个标记或点之间的距离的问题放在地图上,我已经浏览了文档,但在这种情况下没有发现任何帮助。

如果有人知道如何解决这个问题,请帮助我。

谢谢

【问题讨论】:

这里可能对什么是距离有误解,你应该重新检查距离和位移之间的差异。 AFAIK Google Map API 仅提供两点之间的位移,而不是您可能自己处理或计算的距离。 【参考方案1】:

Google Map API V2 中,您有LatLng 对象,因此您不能使用distanceTo(目前)。

考虑到 oldPositionnewPositionLatLng 对象,您可以使用以下代码:

// The computed distance is stored in results[0].
//If results has length 2 or greater, the initial bearing is stored in results[1].
//If results has length 3 or greater, the final bearing is stored in results[2].
float[] results = new float[1];
Location.distanceBetween(oldPosition.latitude, oldPosition.longitude,
                newPosition.latitude, newPosition.longitude, results);

有关Location 类的更多信息请参阅this link

【讨论】:

【参考方案2】:

你可以使用下面的方法来给你准确的结果

public double CalculationByDistance(LatLng StartP, LatLng EndP) 
        int Radius = 6371;// radius of earth in Km
        double lat1 = StartP.latitude;
        double lat2 = EndP.latitude;
        double lon1 = StartP.longitude;
        double lon2 = EndP.longitude;
        double dLat = Math.toRadians(lat2 - lat1);
        double dLon = Math.toRadians(lon2 - lon1);
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
                + Math.cos(Math.toRadians(lat1))
                * Math.cos(Math.toRadians(lat2)) * Math.sin(dLon / 2)
                * Math.sin(dLon / 2);
        double c = 2 * Math.asin(Math.sqrt(a));
        double valueResult = Radius * c;
        double km = valueResult / 1;
        DecimalFormat newFormat = new DecimalFormat("####");
        int kmInDec = Integer.valueOf(newFormat.format(km));
        double meter = valueResult % 1000;
        int meterInDec = Integer.valueOf(newFormat.format(meter));
        Log.i("Radius Value", "" + valueResult + "   KM  " + kmInDec
                + " Meter   " + meterInDec);

        return Radius * c;
    

【讨论】:

你为什么要把它加倍到cc 是做什么的? 真的不是最佳实践...您应该使用位置***.com/a/15351351/1291650 对于一个普通的程序员来说,似乎是一个复杂的解决方案。 不要再使用这个了。使用developers.google.com/maps/documentation/android-sdk/utility【参考方案3】:

您应该使用 android 位置

你可以这样做:

location1.distanceTo(location2);

还有:

float[] results = new float[1];
Location.distanceBetween(latLongA.latitude, latLongA.longitude,
                         latLongB.latitude, latLongB.longitude,
                         results);

您将获得 location1 和 location2 之间的距离(以米为单位)。 在 latLongA 蚂蚁 latLongB 之间。

使用location。

【讨论】:

您不能这样做,因为在 Google API V2 中没有 Location 对象 这是迄今为止最简单的方法!另请参阅我的answer,了解当前位置和标记之间的距离。 Location.distanceBetween 是一个 void 方法,如何从 void 方法获得结果? @SagarHudge 你是认真的吗? 1 公里 == 1000 米...只需使用数学 它没有提供准确的结果。如果有人需要两点之间的实际路线距离,而不仅仅是直接的折线距离怎么办?【参考方案4】:

来晚了,但看到这是 Google 搜索该主题的热门结果之一,我将以另一种方式分享:

在 Google 中使用单行实用程序类 SphericalUtil

SphericalUtil.computeDistanceBetween(latLngFrom, latLngTo)

您将需要utility classes。

您可以使用 gradle 简单地将它们包含在您的项目中:

implementation 'com.google.maps.android:android-maps-utils:0.5+'

【讨论】:

感谢分享这个...有没有办法使用 SphericalUtil 找出两点之间的时间? 此方法不再有效,因为已移除依赖项。 我刚刚检查过,它对我来说很好用。我将版本更新为 0.5,但 0.4 也有效。请参阅文档:developers.google.com/maps/documentation/android-sdk/utility/…【参考方案5】:

所有这些答案都会为您提供直线距离。如果您需要通过公路获取距离,则必须解析 Google 在调用他的服务后发回给您的 JSON。你可以使用这个方法:

public String getDistance(final double lat1, final double lon1, final double lat2, final double lon2)
    String parsedDistance;
    String response;
        Thread thread=new Thread(new Runnable() 
            @Override
            public void run() 
                try 

                    URL url = new URL("http://maps.googleapis.com/maps/api/directions/json?origin=" + lat1 + "," + lon1 + "&destination=" + lat2 + "," + lon2 + "&sensor=false&units=metric&mode=driving");
                    final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("POST");
                    InputStream in = new BufferedInputStream(conn.getInputStream());
                    response = org.apache.commons.io.IOUtils.toString(in, "UTF-8");

                    JSONObject jsonObject = new JSONObject(response);
                    JSONArray array = jsonObject.getJSONArray("routes");
                    JSONObject routes = array.getJSONObject(0);
                    JSONArray legs = routes.getJSONArray("legs");
                    JSONObject steps = legs.getJSONObject(0);
                    JSONObject distance = steps.getJSONObject("distance");
                    parsedDistance=distance.getString("text");

                 catch (ProtocolException e) 
                    e.printStackTrace();
                 catch (MalformedURLException e) 
                    e.printStackTrace();
                 catch (IOException e) 
                    e.printStackTrace();
                 catch (JSONException e) 
                    e.printStackTrace();
                
            
        );
    thread.start();
    try 
        thread.join();
     catch (InterruptedException e) 
        e.printStackTrace();
    
    return parsedDistance;

lat1 和 lon1 是起点坐标,lat2 和 lon2 是目的地坐标。

【讨论】:

我认为这是地球陆地的正确答案,因为距离是根据道路而不是海峡来衡量的,谢谢。【参考方案6】:

@salman khan Usman Kurd 的建议是完美的。我发现唯一可以纠正的是“对于谷歌地图 v2,我们使用 LatLng 类。所以下面是可用于谷歌地图 v2 的 Usman Kurd 的代码。我检查它工作正常。

public double CalculationByDistance(LatLng StartP, LatLng EndP) 
        int Radius=6371;//radius of earth in Km         
        double lat1 = StartP.latitude;
        double lat2 = EndP.latitude;
        double lon1 = StartP.longitude;
        double lon2 = EndP.longitude;
        double dLat = Math.toRadians(lat2-lat1);
        double dLon = Math.toRadians(lon2-lon1);
        double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
        Math.sin(dLon/2) * Math.sin(dLon/2);
        double c = 2 * Math.asin(Math.sqrt(a));
        double valueResult= Radius*c;
        double km=valueResult/1;
        DecimalFormat newFormat = new DecimalFormat("####");
        int kmInDec =  Integer.valueOf(newFormat.format(km));
        double meter=valueResult%1000;
        int  meterInDec= Integer.valueOf(newFormat.format(meter));
        Log.i("Radius Value",""+valueResult+"   KM  "+kmInDec+" Meter   "+meterInDec);

        return Radius * c;
     

【讨论】:

什么是c??为什么我们需要乘以 c【参考方案7】:

计算两个地理点之间距离的简单实用函数:

public static long getDistanceMeters(double lat1, double lng1, double lat2, double lng2) 

    double l1 = toRadians(lat1);
    double l2 = toRadians(lat2);
    double g1 = toRadians(lng1);
    double g2 = toRadians(lng2);

    double dist = acos(sin(l1) * sin(l2) + cos(l1) * cos(l2) * cos(g1 - g2));
    if(dist < 0) 
        dist = dist + Math.PI;
    

    return Math.round(dist * 6378100);

【讨论】:

为什么要通过 PI 增加距离?【参考方案8】:
public class GoogleDirection 

    public final static String MODE_DRIVING = "driving";
    public final static String MODE_WALKING = "walking";
    public final static String MODE_BICYCLING = "bicycling";

    public final static String STATUS_OK = "OK";
    public final static String STATUS_NOT_FOUND = "NOT_FOUND";
    public final static String STATUS_ZERO_RESULTS = "ZERO_RESULTS";
    public final static String STATUS_MAX_WAYPOINTS_EXCEEDED = "MAX_WAYPOINTS_EXCEEDED";
    public final static String STATUS_INVALID_REQUEST = "INVALID_REQUEST";
    public final static String STATUS_OVER_QUERY_LIMIT = "OVER_QUERY_LIMIT";
    public final static String STATUS_REQUEST_DENIED = "REQUEST_DENIED";
    public final static String STATUS_UNKNOWN_ERROR = "UNKNOWN_ERROR";

    public final static int SPEED_VERY_FAST = 1;
    public final static int SPEED_FAST = 2;
    public final static int SPEED_NORMAL = 3;
    public final static int SPEED_SLOW = 4;
    public final static int SPEED_VERY_SLOW = 5;

    private OnDirectionResponseListener mDirectionListener = null;
    private OnAnimateListener mAnimateListener = null;

    private boolean isLogging = false;

    private LatLng animateMarkerPosition = null;
    private LatLng beginPosition = null;
    private LatLng endPosition = null;
    private ArrayList<LatLng> animatePositionList = null;
    private Marker animateMarker = null;
    private Polyline animateLine = null;
    private GoogleMap gm = null;
    private int step = -1;
    private int animateSpeed = -1;
    private int zoom = -1;
    private double animateDistance = -1;
    private double animateCamera = -1;
    private double totalAnimateDistance = 0;
    private boolean cameraLock = false;
    private boolean drawMarker = false;
    private boolean drawLine = false;
    private boolean flatMarker = false;
    private boolean isCameraTilt = false;
    private boolean isCameraZoom = false;
    private boolean isAnimated = false;

    private Context mContext = null;

    public GoogleDirection(Context context)  
        mContext = context;
    

    public String request(LatLng start, LatLng end, String mode) 
        final String url = "http://maps.googleapis.com/maps/api/directions/xml?"
                + "origin=" + start.latitude + "," + start.longitude  
                + "&destination=" + end.latitude + "," + end.longitude 
                + "&sensor=false&units=metric&mode=" + mode;

        if(isLogging)
            Log.i("GoogleDirection", "URL : " + url);
        new RequestTask().execute(new String[] url );
        return url;
    

    private class RequestTask extends AsyncTask<String, Void, Document> 
        protected Document doInBackground(String... url) 
            try 
                HttpClient httpClient = new DefaultHttpClient();
                HttpContext localContext = new BasicHttpContext();
                HttpPost httpPost = new HttpPost(url[0]);
                HttpResponse response = httpClient.execute(httpPost, localContext);
                InputStream in = response.getEntity().getContent();
                DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
                return builder.parse(in);
             catch (IOException e) 
                e.printStackTrace();
             catch (ParserConfigurationException e) 
                e.printStackTrace();
             catch (SAXException e) 
                e.printStackTrace();
             
            return null;
        

        protected void onPostExecute(Document doc) 
            super.onPostExecute(doc);
            if(mDirectionListener != null)
                mDirectionListener.onResponse(getStatus(doc), doc, GoogleDirection.this);
        

        private String getStatus(Document doc) 
            NodeList nl1 = doc.getElementsByTagName("status");
            Node node1 = nl1.item(0);
            if(isLogging)
                Log.i("GoogleDirection", "Status : " + node1.getTextContent());
            return node1.getTextContent();
        
    

    public void setLogging(boolean state) 
        isLogging = state;
    

    public String getStatus(Document doc) 
        NodeList nl1 = doc.getElementsByTagName("status");
        Node node1 = nl1.item(0);
        if(isLogging)
            Log.i("GoogleDirection", "Status : " + node1.getTextContent());
        return node1.getTextContent();
    

    public String[] getDurationText(Document doc) 
        NodeList nl1 = doc.getElementsByTagName("duration");
        String[] arr_str = new String[nl1.getLength() - 1];
        for(int i = 0 ; i < nl1.getLength() - 1 ; i++) 
            Node node1 = nl1.item(i);
            NodeList nl2 = node1.getChildNodes();
            Node node2 = nl2.item(getNodeIndex(nl2, "text"));
            arr_str[i] = node2.getTextContent();
            if(isLogging)
                Log.i("GoogleDirection", "DurationText : " + node2.getTextContent());
        
        return arr_str;
    

    public int[] getDurationValue(Document doc) 
        NodeList nl1 = doc.getElementsByTagName("duration");
        int[] arr_int = new int[nl1.getLength() - 1];
        for(int i = 0 ; i < nl1.getLength() - 1 ; i++) 
            Node node1 = nl1.item(i);
            NodeList nl2 = node1.getChildNodes();
            Node node2 = nl2.item(getNodeIndex(nl2, "value"));
            arr_int[i] = Integer.parseInt(node2.getTextContent());
            if(isLogging)
                Log.i("GoogleDirection", "Duration : " + node2.getTextContent());
        
        return arr_int;
    

    public String getTotalDurationText(Document doc) 
        NodeList nl1 = doc.getElementsByTagName("duration");
        Node node1 = nl1.item(nl1.getLength() - 1);
        NodeList nl2 = node1.getChildNodes();
        Node node2 = nl2.item(getNodeIndex(nl2, "text"));
        if(isLogging)
            Log.i("GoogleDirection", "TotalDuration : " + node2.getTextContent());
        return node2.getTextContent();
    

    public int getTotalDurationValue(Document doc) 
        NodeList nl1 = doc.getElementsByTagName("duration");
        Node node1 = nl1.item(nl1.getLength() - 1);
        NodeList nl2 = node1.getChildNodes();
        Node node2 = nl2.item(getNodeIndex(nl2, "value"));
        if(isLogging)
            Log.i("GoogleDirection", "TotalDuration : " + node2.getTextContent());
        return Integer.parseInt(node2.getTextContent());
    

    public String[] getDistanceText(Document doc) 
        NodeList nl1 = doc.getElementsByTagName("distance");
        String[] arr_str = new String[nl1.getLength() - 1];
        for(int i = 0 ; i < nl1.getLength() - 1 ; i++) 
            Node node1 = nl1.item(i);
            NodeList nl2 = node1.getChildNodes();
            Node node2 = nl2.item(getNodeIndex(nl2, "text"));
            arr_str[i] = node2.getTextContent();
            if(isLogging)
                Log.i("GoogleDirection", "DurationText : " + node2.getTextContent());
        
        return arr_str;
    

    public int[] getDistanceValue(Document doc) 
        NodeList nl1 = doc.getElementsByTagName("distance");
        int[] arr_int = new int[nl1.getLength() - 1];
        for(int i = 0 ; i < nl1.getLength() - 1 ; i++) 
            Node node1 = nl1.item(i);
            NodeList nl2 = node1.getChildNodes();
            Node node2 = nl2.item(getNodeIndex(nl2, "value"));
            arr_int[i] = Integer.parseInt(node2.getTextContent());
            if(isLogging)
                Log.i("GoogleDirection", "Duration : " + node2.getTextContent());
        
        return arr_int;
    

    public String getTotalDistanceText(Document doc) 
        NodeList nl1 = doc.getElementsByTagName("distance");
        Node node1 = nl1.item(nl1.getLength() - 1);
        NodeList nl2 = node1.getChildNodes();
        Node node2 = nl2.item(getNodeIndex(nl2, "text"));
        if(isLogging)
            Log.i("GoogleDirection", "TotalDuration : " + node2.getTextContent());
        return node2.getTextContent();
    

    public int getTotalDistanceValue(Document doc) 
        NodeList nl1 = doc.getElementsByTagName("distance");
        Node node1 = nl1.item(nl1.getLength() - 1);
        NodeList nl2 = node1.getChildNodes();
        Node node2 = nl2.item(getNodeIndex(nl2, "value"));
        if(isLogging)
            Log.i("GoogleDirection", "TotalDuration : " + node2.getTextContent());
        return Integer.parseInt(node2.getTextContent());
    

    public String getStartAddress(Document doc) 
        NodeList nl1 = doc.getElementsByTagName("start_address");
        Node node1 = nl1.item(0);
        if(isLogging)
            Log.i("GoogleDirection", "StartAddress : " + node1.getTextContent());
        return node1.getTextContent();
    

    public String getEndAddress(Document doc) 
        NodeList nl1 = doc.getElementsByTagName("end_address");
        Node node1 = nl1.item(0);
        if(isLogging)
            Log.i("GoogleDirection", "StartAddress : " + node1.getTextContent());
        return node1.getTextContent();
    

    public String getCopyRights(Document doc) 
        NodeList nl1 = doc.getElementsByTagName("copyrights");
        Node node1 = nl1.item(0);
        if(isLogging)
            Log.i("GoogleDirection", "CopyRights : " + node1.getTextContent());
        return node1.getTextContent();
    

    public ArrayList<LatLng> getDirection(Document doc) 
        NodeList nl1, nl2, nl3;
        ArrayList<LatLng> listGeopoints = new ArrayList<LatLng>();
        nl1 = doc.getElementsByTagName("step");
        if (nl1.getLength() > 0) 
            for (int i = 0; i < nl1.getLength(); i++) 
                Node node1 = nl1.item(i);
                nl2 = node1.getChildNodes();

                Node locationNode = nl2.item(getNodeIndex(nl2, "start_location"));
                nl3 = locationNode.getChildNodes();
                Node latNode = nl3.item(getNodeIndex(nl3, "lat"));
                double lat = Double.parseDouble(latNode.getTextContent());
                Node lngNode = nl3.item(getNodeIndex(nl3, "lng"));
                double lng = Double.parseDouble(lngNode.getTextContent());
                listGeopoints.add(new LatLng(lat, lng));

                locationNode = nl2.item(getNodeIndex(nl2, "polyline"));
                nl3 = locationNode.getChildNodes();
                latNode = nl3.item(getNodeIndex(nl3, "points"));
                ArrayList<LatLng> arr = decodePoly(latNode.getTextContent());
                for(int j = 0 ; j < arr.size() ; j++) 
                    listGeopoints.add(new LatLng(arr.get(j).latitude
                            , arr.get(j).longitude));
                

                locationNode = nl2.item(getNodeIndex(nl2, "end_location"));
                nl3 = locationNode.getChildNodes();
                latNode = nl3.item(getNodeIndex(nl3, "lat"));
                lat = Double.parseDouble(latNode.getTextContent());
                lngNode = nl3.item(getNodeIndex(nl3, "lng"));
                lng = Double.parseDouble(lngNode.getTextContent());
                listGeopoints.add(new LatLng(lat, lng));
            
        

        return listGeopoints;
    

    public ArrayList<LatLng> getSection(Document doc) 
        NodeList nl1, nl2, nl3;
        ArrayList<LatLng> listGeopoints = new ArrayList<LatLng>();
        nl1 = doc.getElementsByTagName("step");
        if (nl1.getLength() > 0) 
            for (int i = 0; i < nl1.getLength(); i++) 
                Node node1 = nl1.item(i);
                nl2 = node1.getChildNodes();

                Node locationNode = nl2.item(getNodeIndex(nl2, "end_location"));
                nl3 = locationNode.getChildNodes();
                Node latNode = nl3.item(getNodeIndex(nl3, "lat"));
                double lat = Double.parseDouble(latNode.getTextContent());
                Node lngNode = nl3.item(getNodeIndex(nl3, "lng"));
                double lng = Double.parseDouble(lngNode.getTextContent());
                listGeopoints.add(new LatLng(lat, lng));
            
        

        return listGeopoints;
    

    public PolylineOptions getPolyline(Document doc, int width, int color) 
        ArrayList<LatLng> arr_pos = getDirection(doc);
        PolylineOptions rectLine = new PolylineOptions().width(dpToPx(width)).color(color);
        for(int i = 0 ; i < arr_pos.size() ; i++)        
            rectLine.add(arr_pos.get(i));
        return rectLine;
    

    private int getNodeIndex(NodeList nl, String nodename) 
        for(int i = 0 ; i < nl.getLength() ; i++) 
            if(nl.item(i).getNodeName().equals(nodename))
                return i;
        
        return -1;
    

    private ArrayList<LatLng> decodePoly(String encoded) 
        ArrayList<LatLng> poly = new ArrayList<LatLng>();
        int index = 0, len = encoded.length();
        int lat = 0, lng = 0;
        while (index < len) 
            int b, shift = 0, result = 0;
            do 
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
             while (b >= 0x20);
            int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lat += dlat;
            shift = 0;
            result = 0;
            do 
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
             while (b >= 0x20);
            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lng += dlng;

            LatLng position = new LatLng((double)lat / 1E5, (double)lng / 1E5);
            poly.add(position);
        
        return poly;
    

    private int dpToPx(int dp) 
        DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
        int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));       
        return px;
    

    public void setOnDirectionResponseListener(OnDirectionResponseListener listener) 
        mDirectionListener = listener;
    

    public void setOnAnimateListener(OnAnimateListener listener) 
        mAnimateListener = listener;
    

    public interface OnDirectionResponseListener 
        public void onResponse(String status, Document doc, GoogleDirection gd);
    

    public interface OnAnimateListener 
        public void onFinish();
        public void onStart();
        public void onProgress(int progress, int total);
    

    public void animateDirection(GoogleMap gm, ArrayList<LatLng> direction, int speed
            , boolean cameraLock, boolean isCameraTilt, boolean isCameraZoom
            , boolean drawMarker, MarkerOptions mo, boolean flatMarker
            , boolean drawLine, PolylineOptions po) 
        if(direction.size() > 1) 
            isAnimated = true;
            animatePositionList = direction;
            animateSpeed = speed;
            this.drawMarker = drawMarker;
            this.drawLine = drawLine;
            this.flatMarker = flatMarker;
            this.isCameraTilt = isCameraTilt;
            this.isCameraZoom = isCameraZoom;
            step = 0;
            this.cameraLock = cameraLock;
            this.gm = gm;

            setCameraUpdateSpeed(speed);

            beginPosition = animatePositionList.get(step);
            endPosition = animatePositionList.get(step + 1);
            animateMarkerPosition = beginPosition;

            if(mAnimateListener != null)
                mAnimateListener.onProgress(step, animatePositionList.size());

            if(cameraLock) 
                float bearing = getBearing(beginPosition, endPosition);
                CameraPosition.Builder cameraBuilder = new CameraPosition.Builder()
                    .target(animateMarkerPosition).bearing(bearing);

                if(isCameraTilt) 
                    cameraBuilder.tilt(90);
                else 
                    cameraBuilder.tilt(gm.getCameraPosition().tilt);

                if(isCameraZoom) 
                    cameraBuilder.zoom(zoom);
                else 
                    cameraBuilder.zoom(gm.getCameraPosition().zoom);

                CameraPosition cameraPosition = cameraBuilder.build();
                gm.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
            

            if(drawMarker) 
                if(mo != null)
                    animateMarker = gm.addMarker(mo.position(beginPosition));
                else 
                    animateMarker = gm.addMarker(new MarkerOptions().position(beginPosition));

                if(flatMarker) 
                    animateMarker.setFlat(true);

                    float rotation = getBearing(animateMarkerPosition, endPosition) + 180;
                    animateMarker.setRotation(rotation);
                
            


            if(drawLine) 
                if(po != null) 
                    animateLine = gm.addPolyline(po.add(beginPosition)
                            .add(beginPosition).add(endPosition)
                            .width(dpToPx((int)po.getWidth())));
                else 
                    animateLine = gm.addPolyline(new PolylineOptions()
                            .width(dpToPx(5)));
            

            new Handler().postDelayed(r, speed);
            if(mAnimateListener != null)
                mAnimateListener.onStart();
        
    

    public void cancelAnimated() 
        isAnimated = false;
    

    public boolean isAnimated() 
        return isAnimated;
    

    private Runnable r = new Runnable() 
        public void run() 

            animateMarkerPosition = getNewPosition(animateMarkerPosition, endPosition);

            if(drawMarker)
                animateMarker.setPosition(animateMarkerPosition);


            if(drawLine) 
                List<LatLng> points = animateLine.getPoints();
                points.add(animateMarkerPosition);
                animateLine.setPoints(points);
            

            if((animateMarkerPosition.latitude == endPosition.latitude 
                    && animateMarkerPosition.longitude == endPosition.longitude)) 
                if(step == animatePositionList.size() - 2) 
                    isAnimated = false;
                    totalAnimateDistance = 0;
                    if(mAnimateListener != null)
                        mAnimateListener.onFinish();
                 else 
                    step++;
                    beginPosition = animatePositionList.get(step);
                    endPosition = animatePositionList.get(step + 1);
                    animateMarkerPosition = beginPosition;

                    if(flatMarker && step + 3 < animatePositionList.size() - 1) 
                        float rotation = getBearing(animateMarkerPosition, animatePositionList.get(step + 3)) + 180;
                        animateMarker.setRotation(rotation);
                    

                    if(mAnimateListener != null)
                        mAnimateListener.onProgress(step, animatePositionList.size());
                
            

            if(cameraLock && (totalAnimateDistance > animateCamera || !isAnimated)) 
                totalAnimateDistance = 0;
                float bearing = getBearing(beginPosition, endPosition);
                CameraPosition.Builder cameraBuilder = new CameraPosition.Builder()
                    .target(animateMarkerPosition).bearing(bearing);

                if(isCameraTilt) 
                    cameraBuilder.tilt(90);
                else 
                    cameraBuilder.tilt(gm.getCameraPosition().tilt);

                if(isCameraZoom) 
                    cameraBuilder.zoom(zoom);
                else 
                    cameraBuilder.zoom(gm.getCameraPosition().zoom);

                CameraPosition cameraPosition = cameraBuilder.build();
                gm.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

            

            if(isAnimated) 
                new Handler().postDelayed(r, animateSpeed);
            
        
    ;

    public Marker getAnimateMarker() 
        return animateMarker;
    

    public Polyline getAnimatePolyline() 
        return animateLine;
    

    private LatLng getNewPosition(LatLng begin, LatLng end) 
        double lat = Math.abs(begin.latitude - end.latitude); 
        double lng = Math.abs(begin.longitude - end.longitude);

        double dis = Math.sqrt(Math.pow(lat, 2) + Math.pow(lng, 2));
        if(dis >= animateDistance) 
            double angle = -1;

            if(begin.latitude <= end.latitude && begin.longitude <= end.longitude)
                angle = Math.toDegrees(Math.atan(lng / lat));
            else if(begin.latitude > end.latitude && begin.longitude <= end.longitude)
                angle = (90 - Math.toDegrees(Math.atan(lng / lat))) + 90;
            else if(begin.latitude > end.latitude && begin.longitude > end.longitude)
                angle = Math.toDegrees(Math.atan(lng / lat)) + 180;
            else if(begin.latitude <= end.latitude && begin.longitude > end.longitude)
                angle = (90 - Math.toDegrees(Math.atan(lng / lat))) + 270;

            double x = Math.cos(Math.toRadians(angle)) * animateDistance;
            double y = Math.sin(Math.toRadians(angle)) * animateDistance;
            totalAnimateDistance += animateDistance;
            double finalLat = begin.latitude + x;
            double finalLng = begin.longitude + y;

            return new LatLng(finalLat, finalLng);
         else 
            return end;
        
    

    private float getBearing(LatLng begin, LatLng end) 
        double lat = Math.abs(begin.latitude - end.latitude); 
        double lng = Math.abs(begin.longitude - end.longitude);
         if(begin.latitude < end.latitude && begin.longitude < end.longitude)
            return (float)(Math.toDegrees(Math.atan(lng / lat)));
        else if(begin.latitude >= end.latitude && begin.longitude < end.longitude)
            return (float)((90 - Math.toDegrees(Math.atan(lng / lat))) + 90);
        else if(begin.latitude >= end.latitude && begin.longitude >= end.longitude)
            return  (float)(Math.toDegrees(Math.atan(lng / lat)) + 180);
        else if(begin.latitude < end.latitude && begin.longitude >= end.longitude)
            return (float)((90 - Math.toDegrees(Math.atan(lng / lat))) + 270);
         return -1;
    

    public void setCameraUpdateSpeed(int speed)        
        if(speed == SPEED_VERY_SLOW) 
            animateDistance = 0.000005;
            animateSpeed = 20;
            animateCamera = 0.0004;
            zoom = 19;
         else if(speed == SPEED_SLOW) 
            animateDistance = 0.00001;
            animateSpeed = 20;
            animateCamera = 0.0008;
            zoom = 18;
         else if(speed == SPEED_NORMAL) 
            animateDistance = 0.00005;
            animateSpeed = 20;
            animateCamera = 0.002;
            zoom = 16;
         else if(speed == SPEED_FAST) 
            animateDistance = 0.0001;
            animateSpeed = 20;
            animateCamera = 0.004;
            zoom = 15;
         else if(speed == SPEED_VERY_FAST) 
            animateDistance = 0.0005;
            animateSpeed = 20;
            animateCamera = 0.004;
            zoom = 13;
         else 
            animateDistance = 0.00005;
            animateSpeed = 20;
            animateCamera = 0.002;
            zoom = 16;
        
    

//主要活动

public class MapActivity extends ActionBarActivity 

    GoogleMap map = null;
    GoogleDirection gd;

    LatLng start,end;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);

        start = new LatLng(13.744246499553903, 100.53428772836924);
        end = new LatLng(13.751279688694071, 100.54316081106663);


        map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
        map.animateCamera(CameraUpdateFactory.newLatLngZoom(start, 15));

        gd = new GoogleDirection(this);
        gd.setOnDirectionResponseListener(new GoogleDirection.OnDirectionResponseListener() 
            public void onResponse(String status, Document doc, GoogleDirection gd) 
                Toast.makeText(getApplicationContext(), status, Toast.LENGTH_SHORT).show();

                gd.animateDirection(map, gd.getDirection(doc), GoogleDirection.SPEED_FAST
                        , true, true, true, false, null, false, true, new PolylineOptions().width(8).color(Color.RED));

                map.addMarker(new MarkerOptions().position(start)
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.markera)));

                map.addMarker(new MarkerOptions().position(end)
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.markerb)));

                String TotalDistance = gd.getTotalDistanceText(doc);
                String TotalDuration = gd.getTotalDurationText(doc);
            
        );

        gd.request(start, end, GoogleDirection.MODE_DRIVING);
    

【讨论】:

【参考方案9】:

试试这个

double distance;
Location locationA = new Location("");
locationA.setLatitude(main_Latitude);
locationA.setLongitude(main_Longitude);
Location locationB = new Location("");
locationB.setLatitude(sub_Latitude);
locationB.setLongitude(sub_Longitude);
distance = locationA.distanceTo(locationB)/1000;
kmeter.setText(String.valueOf(distance));
Toast.makeText(getApplicationContext(), ""+distance, Toast.LENGTH_LONG).show();double distance;

【讨论】:

【参考方案10】:

使用 Haversine formula 可以找到两个地理坐标之间的距离。这个公式可以有效地计算球体中的距离,在我们的例子中是地球。

【讨论】:

地球不是球形而是椭圆形谷歌使用墨卡托投影! 这个答案与问题无关。此外,最好在此处包含链接答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。【参考方案11】:

这是确定时长和距离的简单而完美的代码

第 1 步;(添加此内容并在您的 gradle 中同步)

 implementation 'com.android.volley:volley:1.0.0'  

第 2 步:(在您的触发方法中写入)

 public void clicked(View view) throws JSONException   

      JSONObject locationJsonObject = new JSONObject();
             locationJsonObject.put("origin", "54.406505,18.67708");
             locationJsonObject.put("destination", "54.446251,18.570993");
             LatlngCalc(locationJsonObject);
 

第 3 步:(在您的班级中复制和粘贴)

 private void LatlngCalc(JSONObject locationJsonObject) throws JSONException 

     RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
     String url = "https://maps.googleapis.com/maps/api/distancematrix/" +
                 "json?origins=" + locationJsonObject.getString("origin") + "&destinations=" + locationJsonObject.getString("destination") + "&mode=driving&" +
                 "language=en-EN&sensor=false" + "&key=" + /*Insert Your API Key Here */;

     StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
             new Response.Listener<String>() 
                 @Override
                 public void onResponse(String response) 

                     mTextView.setText("Response is: " + response.substring(0, 500));
                 
             , new Response.ErrorListener() 
         @Override
         public void onErrorResponse(VolleyError error) 
             mTextView.setText("That didn't work!");
         
     );
     queue.add(stringRequest);  
 

【讨论】:

【参考方案12】:

要获得两点之间的距离,请尝试此代码..

public static float GetDistanceFromCurrentPosition(double lat1,double lng1, double lat2, double lng2)
 
        double earthRadius = 3958.75;

        double dLat = Math.toRadians(lat2 - lat1);

        double dLng = Math.toRadians(lng2 - lng1);

        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
                + Math.cos(Math.toRadians(lat1))
                * Math.cos(Math.toRadians(lat2)) * Math.sin(dLng / 2)
                * Math.sin(dLng / 2);

        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        double dist = earthRadius * c;

        int meterConversion = 1609;

        return new Float(dist * meterConversion).floatValue();

    

【讨论】:

【参考方案13】:

您可以使用此功能。我在我的项目中使用过它。

public String getDistance(LatLng my_latlong, LatLng frnd_latlong) 
    Location l1 = new Location("One");
    l1.setLatitude(my_latlong.latitude);
    l1.setLongitude(my_latlong.longitude);

    Location l2 = new Location("Two");
    l2.setLatitude(frnd_latlong.latitude);
    l2.setLongitude(frnd_latlong.longitude);

    float distance = l1.distanceTo(l2);
    String dist = distance + " M";

    if (distance > 1000.0f) 
        distance = distance / 1000.0f;
        dist = distance + " KM";
    
    return dist;

【讨论】:

你把城镇的名字放在位置类里面?? 此函数用于计算两点之间的距离,不用于城镇/街道名称。 请问,位置构造函数中的字符串有什么用...Location l2 = new Location("Two") 每个点都有一个经度和纬度,假设这里我们不知道地名但是我们可以得到位置数据。这里 Location l2 = new Location("Two") two 是第二个位置,将由 Two 标识。这是一个标签。【参考方案14】:

这是一个老问题,有老答案。我想强调一种计算两点之间距离的更新方法。现在我们应该熟悉实用程序类“SphericalUtil”。您可以使用它来检索距离。

double distance = SphericalUtil.computeDistanceBetween(origin, dest);

【讨论】:

【参考方案15】:

在 android 谷歌地图应用程序中,有一种非常简单的方法可以找到 2 个位置之间的距离,请按照以下简单步骤进行操作:

    当您第一次打开应用程序时,从下拉菜单中转到“您的时间线” 左上角的菜单。

    打开新的windwo 后,从右上角菜单的设置中进行选择,然后选择“添加地点”。

    添加您的地点并将它们命名为类似 point 1 、 point 2 或任何容易记住的名称。 添加并标记您的地点后,返回您的 Google 应用程序的主窗口。 单击右下角带有箭头的蓝色圆圈。 将打开一个新的windwo,您可以在顶部看到两个文本字段,您可以在其中添加“从位置”和“距离位置”。 单击任何文本字段并在第 3 点中输入您保存的位置。 单击另一个文本字段并添加您的下一个保存位置。 通过这样做,谷歌地图将计算两个位置之间的距离,并在地图上显示蓝色路径..

祝你好运

【讨论】:

问题是关于如何以编程方式在Android中找到两点之间的距离。这个答案是错误的。

以上是关于使用 Google Map API V2 查找地图上两点之间的距离的主要内容,如果未能解决你的问题,请参考以下文章