有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java计算出伦敦经纬度坐标的50英里半径

我编写了一个JavaAPI,它使用另一个API,它是一个用户列表,具有JSON格式的以下属性。用户有名字、姓氏、IP地址、电子邮件以及纬度和经度的位置坐标

编写的JavaAPI应该能够获得居住在伦敦和/或居住在50英里半径范围内的所有用户。 我的答案是否定的,因为我无法计算出检查居住在伦敦或方圆50英里范围内的用户所需的公式

以下是我的Java API:

package com.company;

import org.json.JSONArray;
import org.json.JSONObject;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Main
{


    public static void main(String[] args)
    {
       // Using java.net.http.HttpClient
       HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://bpdts-test-app.herokuapp.com/city/London/users")).build();
        client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                .thenApply(HttpResponse::body)
                .thenApply(Main::parse)
                .join();
    }

    // Parse the returned JSON data
    public static String parse(String responseBody)
    {
        System.out.println("People who live in London");
        JSONArray usersLondon = new JSONArray((responseBody));
        for (int i = 0; i < usersLondon.length(); i++)
        {
            JSONObject userLondon = usersLondon.getJSONObject(i);
            int id = userLondon.getInt("id");
            String first_name = userLondon.getString("first_name");
            String last_name = userLondon.getString("last_name");
            String email = userLondon.getString("email");
            String ip_address = userLondon.getString("ip_address");
            int latitude = userLondon.getInt("latitude");
            int longitude = userLondon.getInt("longitude");
            System.out.println("id: " + id + " " + "first name: " + first_name + " " + "last name: " + last_name + " " + "email: " + email + " "
                    + "IP Address: " + ip_address + " " + "latitude: " + latitude + " " + "longtitude: " + longitude);
        }
         return null;
    }
}

所以它只返回6个用户,我知道这是不正确的。为了测试API中用户的坐标是否居住在伦敦和/或居住在伦敦50英里半径范围内,数学公式是什么

谢谢你的帮助


共 (1) 个答案

  1. # 1 楼答案

    正确准确地计算地球上两点之间距离的方法是使用Inverse/Forward formulas(写于1975年;据我所知,从那时起,没有人能想出更好的公式)

    由于距离较短,您可能可以使用基于球体的计算,但如果您想真正做到正确,则可以使用“反向/正向”方法。这是因为我们的星球不是一个完美的球体。两极之间的距离略小于赤道直径,因此这颗行星是一个“挤压”球体,正式名称为扁球体。在导航和计算距离时,这种差异就足够重要了,除非这些距离非常小

    翻译原始的逆向/正向Fortran代码是可能的(我已经为多个项目做过),但是使用这样做的免费库(如this one)可能会更容易

    描述行星极地和赤道直径之间差异的数字称为“参考椭球体”最常用的是WGS84椭球体,它对于大多数用途来说都足够精确。碰巧上面的类定义了一个方便的静态WGS84实例

    在计算任何东西之前,首先需要定义“50英里半径范围内”的含义。离什么不到50英里?伦敦市中心

    伦敦位于51°30′26〃N 0°7′39〃W,这似乎是距离计算的合理起点

    传统上,在进行计算时,纬度和经度以十进制度数表示,这意味着一个双精度浮点数(即Java double),其整数部分是度数,小数部分是分和秒。按照惯例,正值为北或东,负值为南或西

    因此,50°30′N 99°15′W是以十进制度数表示的50.5的纬度和-99.25的经度

    您的代码以整数形式获取纬度和经度。我非常怀疑您的位置是否为整数度,因为很少有位置正好位于北纬49度。只有您知道这些int值是如何表示分和秒的。由您将这些值转换为十进制度数

    一旦以十进制度数表示伦敦的位置,并且知道如何将用户位置转换为十进制度数,就可以调用上面链接到的Geodesic类的Inverse方法:

    public static List<User> parse(String responseBody)
    {
        List<User> qualifyingUsers = new ArrayList<>();
    
        // 51 deg 30 min 26 sec N
        double londonLat = 51 + (30 / 60.0) + (26 / 60.0 / 60.0);
        // 0 deg 7 min 39 sec W
        double londonLon = 0 - (7 / 60.0) - (39 / 60.0 / 60.0);
    
        for (int i = 0; i < usersLondon.length(); i++)
        {
            JSONObject userLondon = usersLondon.getJSONObject(i);
            // ...
            int latitude = userLondon.getInt("latitude");
            int longitude = userLondon.getInt("longitude");
    
            double userLat = convertToDecimalDegrees(latitude);
            double userLon = convertToDecimalDegrees(longitude);
    
            GeodesicData result =
                Geodesic.WGS84.Inverse(londonLat, londonLon, userLat, userLon);
    
            double distanceInMeters = result.s12;
            double distanceInMiles = distanceInMeters / 1609.34;
    
            if (distanceInMiles <= 50)
            {
                User user = new User();
                user.setId(id);
                user.setFirstName(first_name);
                // etc.
    
                qualifyingUsers.add(user);
            }
        }
    
        return qualifyingUsers;
    }