SpringBoot 定位判断工具类(两经纬度点之间的距离、经纬度是否在圆/多边形区域内)

一、前言

经纬度之间的距离是扒的高德地图的Android的SDK的源码,精度方面请自行体验与测试;
判断是否在区域范围内的代码是用的jts;

二、代码

【jts依赖】

		<dependency>
			<groupId>org.locationtech.jts</groupId>
			<artifactId>jts-core</artifactId>
			<version>1.19.0</version>
		</dependency>

【判断当前定位点是否在项目中 工具类】

public class PositioningUtil {
    /**
     * 判断定位是否在项目中
     * @param v 项目
     * @param lng 经度
     * @param lat 纬度
     * @return -1即false ,0即true但是多边形,>0即距离
     */
    public static Double checkAddressInProject(ProjectVo v, BigDecimal lng, BigDecimal lat) {
        if(v == null) {
            return -1.0;
        }
        if (lng != null && lat != null && lng.compareTo(new BigDecimal("0.000000000000")) > 0 && lat.compareTo(new BigDecimal("0.000000000000")) > 0) {
            if (v.getMarkerType() == 1) {//如果是圆
                return GeoUtil.calculateLineDistance(lat.doubleValue(), lng.doubleValue(),
                        v.getLat().doubleValue(), v.getLng().doubleValue()) < v.getRadius() ;
            } else if (v.getMarkerType() == 2) {
                //多边形点集合字符串
                String polygonalCoordinate = v.getPolygonalCoordinate();
                //处理字符串
                Gson gson = new Gson();
                List<List<List<Double>>> coordinates = gson.fromJson(polygonalCoordinate, new TypeToken<List<List<List<Double>>>>() {
                }.getType());
                if (coordinates == null || coordinates.isEmpty()) {
                    return -1.0;
                }
                for (List<List<Double>> corList : coordinates) {
                    Coordinate[] coordinates1 = new Coordinate[corList.size() + 1];
                    for (int i = 0; i < corList.size(); i++) {
                        Double longitude = corList.get(i).get(0);
                        Double latitude = corList.get(i).get(1);
                        if (longitude == null || latitude == null) {//数据异常
                            return -1.0;
                        }
                        Coordinate coordinate = new Coordinate(longitude, latitude);
                        coordinates1[i] = coordinate;
                    }
                    coordinates1[corList.size()] = new Coordinate(corList.get(0).get(0), corList.get(0).get(1));
                    if (GeoUtil.isPointInPolygon(lat.doubleValue(), lng.doubleValue(), coordinates1)) {
                        return 0.0;//只需要定位在其中一个的多边形范围内
                    }
                }
                return -1.0;
            }
            return -1.0;
        } else {
            return -1.0;
        }
    }
}

【工具类】

public class GeoUtil {
    /**
     * 判断坐标之间的距离
     *(高德地图Android库的反编译源码)
     * @param longitude 待判断经度
     * @param latitude  待判断纬度
     * @param centerLon 中心点经度
     * @param centerLat 中心点纬度
     * @return
     */
    public static Double calculateLineDistance(double longitude, double latitude, double centerLon, double centerLat) {
        if(longitude==0 || latitude==0 || centerLat==0 || centerLon==0){
            return -1.0;
        }
        longitude *= 0.01745329251994329;
        latitude *= 0.01745329251994329;
        centerLon *= 0.01745329251994329;
        centerLat *= 0.01745329251994329;
        double var10 = Math.sin(longitude);
        double var12 = Math.sin(latitude);
        double var14 = Math.cos(longitude);
        double var16 = Math.cos(latitude);
        double var18 = Math.sin(centerLon);
        double var20 = Math.sin(centerLat);
        double var22 = Math.cos(centerLon);
        double var24 = Math.cos(centerLat);
        double[] var28 = new double[3];
        double[] var29 = new double[3];
        var28[0] = var16 * var14;
        var28[1] = var16 * var10;
        var28[2] = var12;
        var29[0] = var24 * var22;
        var29[1] = var24 * var18;
        var29[2] = var20;
        double distance = Math.asin(Math.sqrt((var28[0] - var29[0]) * (var28[0] - var29[0]) + (var28[1] - var29[1]) * (var28[1] - var29[1]) + (var28[2] - var29[2]) * (var28[2] - var29[2])) / 2.0) * 1.27420015798544E7;
        return distance ;
    }

 
    /**
     * 判断是否在多边形区域内
      * @param latitude 经度
     * @param longitude 纬度
     * @param polygonCoordinates 多边形点集合
     * @return
     */
    public static boolean isPointInPolygon(double latitude, double longitude, Coordinate[] polygonCoordinates) {
        GeometryFactory geometryFactory = new GeometryFactory();
        Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
        Polygon polygon = geometryFactory.createPolygon(polygonCoordinates);

        return polygon.touches(point) || polygon.contains(point);
    }
}

【ProjectVo类】(请自行根据需求进行修改)

@Data
@Api(value = "")
public class ProjectVo implements Serializable {
    private static final long serialVersionUID = 1L;

	/**
	 * 经度
	 */
	@ApiModelProperty(value="经度")
	private BigDecimal lng;

	/**
	 * 维度
	 */
	@ApiModelProperty(value="维度")
	private BigDecimal lat;

	/**
	 * 半径
	 */
	@ApiModelProperty(value = "半径")
	private Double radius;

	/**
	 * 标记类型:1圆,2多边形
	 */
	@ApiModelProperty(value = "标记类型:1圆,2多边形")
	private Integer markerType;

	/**
	 * 多边形区域JSON(二维数组的串)
	 */
	@ApiModelProperty(value = "多边形区域JSON")
	private String polygonalCoordinate;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浅梦曾倾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值