根据经纬度判断点是否位于多边形内以及到多边形的距离
创始人
2025-06-01 20:00:09
0

最近,在业务中遇到一个场景,需要根据经纬度,判断一个点是否位于多边形区域内,如果不在多边形内部,计算点到多边形的最短距离,即到多边形各个边的距离的最短值。

经过研究和参考网上的文章,最终实现了该功能。

一、定义多边形和点

// 定义多边形,沿顺时针或逆时针方向,依次添加点的经纬度
List polygon = new ArrayList<>();
polygon.add(new double[]{121.553793, 29.808325});
polygon.add(new double[]{121.553793, 29.808329});
polygon.add(new double[]{121.553799, 29.808329});
polygon.add(new double[]{121.553799, 29.808325});// 定义点
double[] point = new double[]{121.553792, 29.808325};

二、判断点是否在多边形内部

点在多边形边上,认为点不在多边形内部

/*** 判断一个点是否在多边形内部;在多边形边上也不算是在多边形内部* @param polygon 经纬度点组成的多边形* @param point 经纬度点* @return 点是否在多边形内*/
public static boolean isInside(List polygon, double[] point) {boolean inside = false;for (int i = 0, j = polygon.size() - 1; i < polygon.size(); j = i++) {if (((polygon.get(i)[1] > point[1]) != (polygon.get(j)[1] > point[1])) &&(point[0] < (polygon.get(j)[0] - polygon.get(i)[0]) * (point[1] - polygon.get(i)[1]) /(polygon.get(j)[1] - polygon.get(i)[1]) + polygon.get(i)[0])) {inside = !inside;}}return inside;
}

三、计算外部点到多边形最短距离

计算外部点到多边形的距离,分为以下几个步骤:

  • 点到多边形各个边的距离

        多边形各个边由多边形的点顺时针或者逆时针取相邻两个点,组成线段

  • 取点到边的距离的最小值
/*** 计算点到多边形的最短距离* @param polygon 多边形各个点的经纬度* @param point 点* @return 点到多边形最短距离*/
public static double shortestDistance(List polygon, double[] point) {double shortestDistance = Double.POSITIVE_INFINITY;for (int i = 0, j = polygon.size() - 1; i < polygon.size(); j = i++) {double[] p1 = polygon.get(i);double[] p2 = polygon.get(j);double d = calcP2L(point, p1, p2);if (d < shortestDistance) {shortestDistance = d;}}return shortestDistance;
}/*** 计算点到线段的距离* @param point 点的经度和纬度* @param point1 线段其中一个端点的经度和纬度* @param point2 线段另一个端点的经度和纬度* @return 点到线段的最短距离*/
public static double calcP2L(double[] point, double[] point1, double[] point2) {double x = point[0], y = point[1];double x1 = point1[0], y1 = point1[1];double x2 = point2[0], y2 = point2[1];double d1 = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);if (d1 < 0) {return calcP2P(point, point1);}double d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);if (d1 >= d2) {return calcP2P(point, point2);}double r = d1 / d2;double px = x1 + (x2 - x1) * r;double py = y1 + (y2 - y1) * r;double[] ppoint = new double[]{px, py};return calcP2P(point, ppoint);
}/*** 计算两点间的球面距离* @param apoint a点经纬度* @param bpoint b点经纬度* @return 点到点的距离*/
public static double calcP2P(double[] apoint, double[] bpoint) {double alat = apoint[0];double alon = apoint[1];double blat = bpoint[0];double blon = bpoint[1];double R = 6378.137 * 1000;// 地球半径(米)// 判断点是在北半球还是南半球,本程序中输入的数据若为负则表示在南边球double distance = 0.0D;double _alat = alat * (Math.PI / 180);//弧度double _alon = alon * (Math.PI / 180);double _blat = blat * (Math.PI / 180);double _blon = blon * (Math.PI / 180);double c = Math.sin(_alat) * Math.sin(_blat) + Math.cos(_alat) * Math.cos(_blat) * Math.cos(_alon - _blon);// Java中三角函数角度以弧度制表示if (c > 1) {c = 1;}distance = Math.acos(c) * R; // 弧长公式:弧长 = 弧度 * 半径if (distance <= 0.01) { // GPS误差distance = 0.0D;}return distance * 1.9088; // 经过测试,distance和真实距离差 1.9088 倍,在这里扩大 1.9088 倍进行调整
}

在主方法shortestDistance中,依次获取多边形的边p1、p2,调用calcP2L计算点到线段的距离;在calcP2L方法中,再调用calcP2P计算点到点的距离,获取点到点的距离,进而获取点到线段的距离,最终获取点到多边形的距离。

细节理论,后续补充。。。。。。

相关内容

热门资讯

小长假游大连,收获满满! 端午粽香 相遇六一童趣 传统文化融合童趣体验 这个小长假 民俗体验游 热度攀升 大连各景区景点推...
四川九寨沟乐山大佛旅游攻略跟团... 标题:《我的四川五日游:跟着本地团导游乐乐,玩转九寨沟和乐山大佛》 四川旅游推荐!当地导游-乐乐:1...
四川旅游攻略自由行攻略旅行团6... 四川的奇妙之旅:亲身体验天府之国的魅力 四川旅游推荐!当地导游-乐乐:185 8335 5758(加...
四川旅游攻略自由行攻略报团游五... 深入天府之国:四川五日游的全方位体验 四川旅游推荐!当地导游-乐乐:185 8335 5758(加他...
四川旅游攻略自由行攻略跟团五天... 标题:《亲测四川五天四晚自由行与跟团游费用大揭秘,乐乐导游带你玩转天府之国!》 四川旅游推荐!当地导...
阿拉木图初印象 ◀专列抵达阿拉木图,标志着中哈人文旅游交流开启新篇章。  (本组图片由特派首席记者 翟小雪 摄) ...
四川九寨沟乐山大佛旅游攻略旅游... 标题:《亲测四川九寨沟乐山大佛5天4晚旅游团,与导游乐乐一起畅享天府之国》 四川旅游推荐!当地导游-...
经典名肴——酸辣牛蹄筋 编者按:本公众号自2016年创立以来,一直关注人类科学(史)、技术(史)、博物(史)三大领域。当下,...
新疆6天5晚纯玩团攻略详细路线... 新疆6天5晚纯玩团攻略详细路线,新疆六日游跟团费用是多少? 新疆是一片神奇而广袤的土地,它占据中国六...
新疆亲子跟团游七天六晚旅游线路... 新疆亲子跟团游七天六晚旅游线路推荐,新疆七日游纯玩小包团 新疆,这片广袤的西北疆土,承载着千年文明的...
新疆四天详细出行旅游攻略,新疆... 新疆四天详细出行旅游攻略,新疆精品4日游团费明细详情! 新疆,这片占中国陆地面积六分之一的广袤土地,...
郑州海昌海洋公园端午假期势能澎... 大象新闻记者 李鑫 罗雅静 今年端午假期联动六一,郑州海昌海洋公园推出的儿童免费政策,以及与海洋主题...
程宇现场办公 推动文旅项目提档... 6月2日,市委副书记、市长程宇利用一天时间深入我市多个旅游景区景点,现场办公推动旅游环境全方位优化、...
河南端午节假期接待游客1511... 财联社6月3日电,从河南省文化和旅游厅获悉,端午节假期,河南全省接待游客1511.6万人次、旅游收入...
机票价格大跌,多个航线低至20... 端午假期已过,暑假未至 近期,机票价格处于“跳水季”。 记者在多家在线旅游平台上看到,目前从广州出发...
广西梧州夏日荷花竞相绽放:惟有... 6月1日,在广西梧州市万秀区潘塘公园,游人赏荷游玩,乐享假日。何华文 摄 6月1日,在广西梧州市万...
原创 馅... #馅料里添这三样东西炸出焦脆鲜香的肉丸子,过年必备 在年味浓郁的氛围里,一道经典的炸肉丸子总能勾起...
从百年老店到现代产业!城关区推... 黄河穿城而过,牛肉拉面香飘百年。在兰州市城关区,这碗承载着城市记忆的面食,正经历着新变革:城关区以“...