将一个市区划分成多个区域,并判断某个地点属于某个区域
package lngLatDdemo;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
/**
* 根据订单的经纬度归属所在的区域
*
* @author fmz
* @date: 2019年6月26日 下午2:12:02
*/
public class test {
// 1,2,3,4,5,6,中点,17---城东
public static String partitionLocation1 = "31.360917_118.742418,31.245893_118.846010,31.326869_119.180899,31.292315_119.426963,31.086699_119.721966,30.608496_119.480609,"
+ "30.638329_119.388623,30.65089247415342_118.94369351839742";
// 6,7,8,9,10,11,12,13,中点 ---城南
public static String partitionLocation2 = "30.638329_119.388623,30.542828_119.296636,30.538847_119.361027,30.359519_119.439215,30.240531_119.068970,29.784193_118.848202,"
+ "29.831577_118.549246,29.917260_118.303182,30.65089247415342_118.94369351839742";
// 13,14,15,中点---城西
public static String partitionLocation3 = "29.917260_118.303182,30.345059_117.930637,30.671136_117.907748,30.65089247415342_118.94369351839742";
// 15,16,17,中点---城北
public static String partitionLocation4 = "30.671136_117.907748,31.256266_118.563044,31.360917_118.742418,30.65089247415342_118.94369351839742";
public static void main(String[] args) {
// 被检测的经纬度点
String str = "30.5468200000,117.8578940000";
String[] add = str.split(",");
PageData orderLocation = new PageData();
orderLocation.put("X", add[1]);
orderLocation.put("Y", add[0]);
// 商业区域(百度多边形区域经纬度集合)
if (isInPolygon(orderLocation, partitionLocation1)) {// 在城东
System.out.println("该位置在城东!");
} else if (isInPolygon(orderLocation, partitionLocation2)) {// 在城南
System.out.println("该位置在城南!");
} else if (isInPolygon(orderLocation, partitionLocation3)) {// 在城西
System.out.println("该位置在城西!");
} else if (isInPolygon(orderLocation, partitionLocation4)) {// 在城北
System.out.println("该位置在城北!");
} else {
System.out.println("该位置暂无服务!");
}
// System.out.println("城东:"+isInPolygon(orderLocation,partitionLocation1));
// System.out.println("城南:"+isInPolygon(orderLocation,partitionLocation2));
// System.out.println("城西:"+isInPolygon(orderLocation,partitionLocation3));
// System.out.println("城北:"+isInPolygon(orderLocation,partitionLocation4));
}
/**
* 判断当前位置是否在多边形区域内
*
* @param orderLocation
* 当前点
* @param partitionLocation
* 区域顶点
* @return
*/
public static boolean isInPolygon(PageData orderLocation, String partitionLocation) {
double p_x = Double.parseDouble(orderLocation.getString("X"));
double p_y = Double.parseDouble(orderLocation.getString("Y"));
Point2D.Double point = new Point2D.Double(p_x, p_y);
List<Point2D.Double> pointList = new ArrayList<Point2D.Double>();
String[] strList = partitionLocation.split(",");
for (String str : strList) {
String[] points = str.split("_");
double polygonPoint_x = Double.parseDouble(points[1]);
double polygonPoint_y = Double.parseDouble(points[0]);
Point2D.Double polygonPoint = new Point2D.Double(polygonPoint_x, polygonPoint_y);
pointList.add(polygonPoint);
}
return IsPtInPoly(point, pointList);
}
/**
* 返回一个点是否在一个多边形区域内, 如果点位于多边形的顶点或边上,不算做点在多边形内,返回false
*
* @param point
* @param polygon
* @return
*/
public static boolean checkWithJdkGeneralPath(Point2D.Double point, List<Point2D.Double> polygon) {
java.awt.geom.GeneralPath p = new java.awt.geom.GeneralPath();
Point2D.Double first = polygon.get(0);
p.moveTo(first.x, first.y);
polygon.remove(0);
for (Point2D.Double d : polygon) {
p.lineTo(d.x, d.y);
}
p.lineTo(first.x, first.y);
p.closePath();
return p.contains(point);
}
/**
* 判断点是否在多边形内,如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
*
* @param point
* 检测点
* @param pts
* 多边形的顶点
* @return 点在多边形内返回true,否则返回false
*/
public static boolean IsPtInPoly(Point2D.Double point, List<Point2D.Double> pts) {
int N = pts.size();
boolean boundOrVertex = true; // 如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
int intersectCount = 0;// cross points count of x
double precision = 2e-10; // 浮点类型计算时候与0比较时候的容差
Point2D.Double p1, p2;// neighbour bound vertices
Point2D.Double p = point; // 当前点
p1 = pts.get(0);// left vertex
for (int i = 1; i <= N; ++i) {// check all rays
if (p.equals(p1)) {
return boundOrVertex;// p is an vertex
}
p2 = pts.get(i % N);// right vertex
if (p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)) {// ray
// is
// outside
// of
// our
// interests
p1 = p2;
continue;// next ray left point
}
if (p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)) {// ray
// is
// crossing
// over
// by
// the
// algorithm
// (common
// part
// of)
if (p.y <= Math.max(p1.y, p2.y)) {// x is before of ray
if (p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)) {// overlies
// on a
// horizontal
// ray
return boundOrVertex;
}
if (p1.y == p2.y) {// ray is vertical
if (p1.y == p.y) {// overlies on a vertical ray
return boundOrVertex;
} else {// before ray
++intersectCount;
}
} else {// cross point on the left side
double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y;// cross
// point
// of
// y
if (Math.abs(p.y - xinters) < precision) {// overlies on
// a ray
return boundOrVertex;
}
if (p.y < xinters) {// before ray
++intersectCount;
}
}
}
} else {// special case when ray is crossing through the vertex
if (p.x == p2.x && p.y <= p2.y) {// p crossing over p2
Point2D.Double p3 = pts.get((i + 1) % N); // next vertex
if (p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)) {// p.x
// lies
// between
// p1.x
// &
// p3.x
++intersectCount;
} else {
intersectCount += 2;
}
}
}
p1 = p2;// next ray left point
}
if (intersectCount % 2 == 0) {// 偶数在多边形外
return false;
} else { // 奇数在多边形内
return true;
}
}
}