一、前言
经纬度之间的距离是扒的高德地图的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;
}