Java 某个经纬度是否在genjson文件中

本文介绍了如何使用GeoJSON格式处理地理数据,通过GeoJSON文件判断给定经纬度是否位于特定区域,借助Jackson库解析GeoJSON并实现坐标点的比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GeoJSON是一种对各种地理数据结构进行编码的格式,基于Javascript对象表示法(JavaScript Object Notation, 简称JSON)的地理空间信息数据交换格式。

如果我们要用某个经纬度是否在某个区域的时候,首先是要用到genjson文件,因为省份地图是一个不规则的图形,需要通过描边来确定是否在区域内部。

所以我们需要先解析genjson文件,然后在用经纬度去比较,需要提前导入GenJSON的库

      <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson</artifactId>
            <version>23.5</version>
        </dependency>

创建一个对象

import lombok.Data;

@Data
public class LatLng {

    double lat;
    double lng;


    public LatLng(double lat,double lng){
        this.lat = lat;
        this.lng = lng;
    }
}

工具类:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class GeojsonUtils {


    /**
     *
     * @param path genjson 位置
     * @param lat 纬度
     * @param lng 经度
     * @return
     */
    public static Boolean getGenjsonPosition(String path,Double lat,Double lng){
        try{
            String jsonString = new String(Files.readAllBytes(Paths.get(path)));
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode jsonNode = objectMapper.readTree(jsonString);
            JsonNode coordinatesNode = jsonNode.path("features").get(0).path("geometry").path("coordinates").get(0);
            List<LatLng> coordinatesList = new ArrayList<>();

            for (JsonNode coordinate : coordinatesNode) {
                double rlng = coordinate.get(0).asDouble();
                double rlat = coordinate.get(1).asDouble();
                LatLng point = new LatLng(rlat,rlng);
                coordinatesList.add(point);
            }

            LatLng targetPoint = new LatLng(lat, lng);
            boolean isInArea = false;
            int j = coordinatesList.size() - 1;

            for (int i = 0; i < coordinatesList.size(); i++) {
                LatLng point1 = coordinatesList.get(i);
                LatLng point2 = coordinatesList.get(j);

                if ((point1.getLng() < targetPoint.getLng() && point2.getLng() >= targetPoint.getLng()
                        || point2.getLng() < targetPoint.getLng() && point1.getLng() >= targetPoint.getLng())
                        && (point1.getLat() <= targetPoint.getLat() || point2.getLat() <= targetPoint.getLat())) {
                    if (point1.getLat() + (targetPoint.getLng() - point1.getLng()) / (point2.getLng() - point1.getLng())
                            * (point2.getLat() - point1.getLat()) < targetPoint.getLat()) {
                        isInArea = !isInArea;
                    }
                }

                j = i;
            }

            if (isInArea)  return true; //在区域内部
        }catch (Exception e){

        }
        return false; //不在区域内部

    }

    public static void main(String[] args) {
        String filePath = "C:\\Users\\Administrator\\Desktop\\林长制\\shanxi.geojson";
        System.out.println(getGenjsonPosition(filePath,39.34727,108.94647));
    }

<think>好的,我需要帮助用户解决如何用Java判断一个经纬度是否在给定的圆上。首先,用户的问题是关于如何实现这一点的算法,可能涉及到距离计算和圆的判断。我需要回忆一下相关的知识,并参考提供的引用内容。 根据用户提供的引用[1]和[^2],里面提到了计算两点间距离的方法,以及如何判断是否在圆内。通常,判断是否在圆上需要考虑该点到圆心的距离是否等于圆的半径。不过,由于浮点数计算的精度问题,直接判断相等可能会有困难,可能需要引入一个误差范围。 首先,我需要确认计算两点间距离的公式。地球上的两点经纬度距离计算通常使用Haversine公式,这比欧几里得距离更准确,因为地球是球面。Haversine公式可以计算两个经纬度点之间的大圆距离。 然后,判断该距离是否等于圆的半径。但实际编程中,由于计算精度问题,应该允许一定的误差,比如判断距离与半径的差的绝对值是否小于某个很小的阈值(如1e-6)。 接下来,我需要考虑如何将这些步骤转化为Java代码。可能需要一个方法来计算两个经纬度点之间的距离,另一个方法来判断该距离是否在圆的半径的误差范围内。 另外,用户提供的引用中有一个工具类LanLng,包含经度和纬度。因此,代码中可能需要使用这个类或者类似的类来封装经纬度点。 然后,我需要检查提供的引用是否有现成的代码可以参考。引用[1]提到了计算是否在圆内的方法,但可能只是判断是否在圆内,而不是圆上。需要调整这个方法,把判断条件从“小于等于半径”改为“等于半径(考虑误差)”。 同时,需要注意经纬度的单位,通常是度数,而Haversine公式中需要将度数转换为弧度进行计算。半径可能需要以米或其他单位给出,因此需要确保所有参数的单位一致。 最后,需要编写示例代码,并解释每一步的作用,确保用户能够理解并正确应用。</think>要判断一个经纬度是否位于指定圆上,可以通过以下步骤实现: ### 1. 计算两点间的大圆距离 使用Haversine公式计算给定点与圆心之间的距离: $$d = 2R \arcsin\left( \sqrt{\sin^2\left(\frac{\Delta\phi}{2}\right) + \cos\phi_1 \cos\phi_2 \sin^2\left(\frac{\Delta\lambda}{2}\right)} \right)$$ 其中$\phi$为纬度,$\lambda$为经度,$R$为地球半径(6371公里) ### 2. 判断是否在圆上 通过比较计算距离与圆半径的差值,并设置允许的误差范围(通常用1e-6米级精度) ```java public class GeoUtils { private static final double EARTH_RADIUS = 6378137; // 地球半径(米) // 计算两点间距离(米) public static double getDistance(LanLng point1, LanLng point2) { double lat1 = Math.toRadians(point1.getY_point()); double lng1 = Math.toRadians(point1.getX_point()); double lat2 = Math.toRadians(point2.getY_point()); double lng2 = Math.toRadians(point2.getX_point()); double dLat = lat2 - lat1; double dLng = lng2 - lng1; double a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLng/2) * Math.sin(dLng/2); return EARTH_RADIUS * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); } // 判断是否在圆上(误差范围1毫米) public static boolean isOnCircle(LanLng point, LanLng center, double radius) { double distance = getDistance(point, center); return Math.abs(distance - radius) < 0.001; // 误差阈值设置 } } ``` ### 3. 使用示例 ```java // 创建圆心(经度116.404,纬度39.915) LanLng center = new LanLng(116.404, 39.915); double radius = 500; // 500米半径 // 待检测点 LanLng testPoint = new LanLng(116.405, 39.915); // 判断是否在圆上 boolean result = GeoUtils.isOnCircle(testPoint, center, radius); ``` ### 关键说明 1. **Haversine公式**:比球面余弦公式计算更稳定,适合小距离计算[^1] 2. **误差处理**:因浮点运算精度限制,必须设置误差阈值(示例使用1毫米) 3. **单位统一**:确保所有距离参数使用相同单位(示例使用米) 4. **坐标范围验证**:应先验证经纬度有效性(经度-180~180,纬度-90~90)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值