package com.lxkj.project.location.utils;
import com.lxkj.project.location.domain.TCoordinatePoint;
import com.lxkj.project.location.domain.TLocationInfo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 判断一个点,是否在一个多边形区域内
*/
public class MultiRectUtil {
public static void main(String[] args) {
double pyLng = 116.3383;
double pxLat = 39.9147;
ArrayList
ArrayList
polygonYLng.add(119.388572);
polygonYLng.add(118.094802);
polygonYLng.add(117.724194);
polygonYLng.add(119.418956);
polygonYLng.add(121.147316);
polygonYLng.add(121.075774);
polygonYLng.add(119.388572);
polygonXLat.add(31.14423);
polygonXLat.add(30.769938);
polygonXLat.add(29.666748);
polygonXLat.add(29.394196);
polygonXLat.add(29.312862);
polygonXLat.add(30.734536);
polygonXLat.add(31.14423);
}
public static boolean isPointInPolygon(TLocationInfo locationInfo , List
double px = Double.parseDouble(locationInfo.getLatitude());
double py = Double.parseDouble(locationInfo.getLongitude());
return isPointInPolygon(px, py, list);
}
public static boolean isPointInPolygon(double px, double py, List
List
//获取区域列表
for (TCoordinatePoint coordinatePoint : pointList) {
//如果经度或纬度为空,则略过该点
if (coordinatePoint.getLatitude() == null || coordinatePoint.getLatitude().trim().equals("") ||
coordinatePoint.getLongitude() == null || coordinatePoint.getLongitude().trim().equals("")) {
continue;
}
//判断区域的起点和终点
if (startLat == null || startLng == null) {
startLat = coordinatePoint.getLatitude().trim();
startLng = coordinatePoint.getLongitude().trim();
polygonXLat = new ArrayList
polygonYLng = new ArrayList
} else if (startLat.equals(coordinatePoint.getLatitude().trim()) && startLng.equals(coordinatePoint.getLongitude().trim())) {
startLat = null;
startLng = null;
}
//新增区域点
polygonXLat.add(Double.valueOf(coordinatePoint.getLatitude().trim()));
polygonYLng.add(Double.valueOf(coordinatePoint.getLongitude().trim()));
//如果到达终点,则判断为完整的区域
if (startLat == null || startLng == null) {
Map
districtPoint.put("latitude", polygonXLat);
districtPoint.put("longitude", polygonYLng);
districtList.add(districtPoint);
}
}
if (districtList.size() == 0 && polygonXLat != null && polygonYLng != null) {
Map
districtPoint.put("latitude", polygonXLat);
districtPoint.put("longitude", polygonYLng);
districtList.add(districtPoint);
}
//判断是否在区域中
if (districtList.size() > 0) {
for (Map
boolean isInDistrict = isPointInPolygon(px, py, districtPoint.get("latitude"), districtPoint.get("longitude"));
//只要这个点在某个区域中就判断为在区域中
if (isInDistrict) return true;
}
}
//返回不在区域中
return false;
}
// public static boolean isPointInPolygon(double px, double py, List
// ArrayList
// ArrayList
// for (TCoordinatePoint coordinatePoint : list) {
// polygonXLat.add(Double.valueOf(coordinatePoint.getLatitude().trim()));
// polygonYLng.add(Double.valueOf(coordinatePoint.getLongitude().trim()));
// }
// //判断是否越界
// boolean flag = isPointInPolygon(px, py, polygonXLat, polygonYLng);
// /**
// * 2021.10.29 应急处理:若越界,判断是否在允许误差范围内
// if (!flag) {
// //当判定越界时,与任意点的距离小于x米,均视为不越界
// final double errorRange = 1000d;
// flag = isWithinBoundaryErrorRange(px, py, polygonXLat, polygonYLng, errorRange);
// }*/
// return flag;
// }
/**
*
* @param px 纬度 lat
* @param py 经度 lng
* @param polygonXA 纬度 lat
* @param polygonYA 经度 lng
* @return
*/
public static boolean isPointInPolygon(double px, double py, List
if(polygonYA.size() > 0){//注意:必须把第一个点加入到尾部组成闭合
if(polygonYA.get(polygonYA.size()-1).equals(polygonYA.get(0)) &&
polygonXA.get(polygonXA.size()-1).equals(polygonXA.get(0))){
//已经是闭包
}else{
polygonYA.add(polygonYA.get(0));
polygonXA.add(polygonXA.get(0));
}
}
boolean isInside = false;
double ESP = 1e-9;
int count = 0;
double linePoint1x;
double linePoint1y;
double linePoint2x = 180;
double linePoint2y;
linePoint1x = px;
linePoint1y = py;
linePoint2y = py;
for (int i = 0; i < polygonXA.size() - 1; i++) {
double cx1 = polygonXA.get(i);
double cy1 = polygonYA.get(i);
double cx2 = polygonXA.get(i + 1);
double cy2 = polygonYA.get(i + 1);
if (PointUtil.isPointOnLine(px, py, cx1, cy1, cx2, cy2)) {
return true;
}
if (Math.abs(cy2 - cy1) < ESP) {
continue;
}
if (PointUtil.isPointOnLine(cx1, cy1, linePoint1x, linePoint1y, linePoint2x, linePoint2y)) {
if (cy1 > cy2)
count++;
} else if (PointUtil.isPointOnLine(cx2, cy2, linePoint1x, linePoint1y, linePoint2x, linePoint2y)) {
if (cy2 > cy1)
count++;
} else if (PointUtil.isIntersect(cx1, cy1, cx2, cy2, linePoint1x, linePoint1y, linePoint2x, linePoint2y)) {
count++;
}
}
//System.out.println(count);
if (count % 2 == 1) {
isInside = true;
}
//System.out.println("判断点是否在区域里面:"+py+"--"+px+",结果:"+isInside);
return isInside;
}
/**
* 点距离区域边界最近距离是否在指定误差范围内
* 要结合区域范围内外判断使用
*
* @param lat0
* @param lng0
* @param polygonLat
* @param polygonLng
* @param errorRange 米
* @return
*/
public static boolean isWithinBoundaryErrorRange(double lat0, double lng0, ArrayList
if (errorRange < 0) {
return false;
}
if (polygonLng.size() > 0) {//注意:必须把第一个点加入到尾部组成闭合
if (polygonLng.get(polygonLng.size() - 1).equals(polygonLng.get(0)) && polygonLat.get(polygonLat.size() - 1).equals(polygonLat.get(0))) {
//已经是闭包
} else {
polygonLng.add(polygonLng.get(0));
polygonLat.add(polygonLat.get(0));
}
}
boolean flag = false;
for (int i = 0; i < polygonLat.size() - 1; i++) {
double lat1 = polygonLat.get(i);
double lng1 = polygonLng.get(i);
double lat2 = polygonLat.get(i + 1);
double lng2 = polygonLng.get(i + 1);
double distance = PointUtil.getNearestDistance(lng0, lat0, lng1, lat1, lng2, lat2);
if (Math.abs(distance) <= errorRange) {
flag = true;
break;
}
}
return flag;
}
}