java划分城市为多个区域并判断某个点属于某个区域

将一个市区划分成多个区域,并判断某个地点属于某个区域

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;
		}
	}
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

哎呦喂O_o嗨

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

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

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

打赏作者

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

抵扣说明:

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

余额充值