java 获取两条经纬度线段的交点坐标工具类

网上有线段是否相交的判断方法,但是很少有获取线段交点的坐标的方法
我在这里整合了网上的一些相交的方法,通过相交的xy轴点返推出了经纬度。

拾取坐标系统 可直接复制坐标测试:
链接: 坐标拾取系统-百度

使用方法可以按GisCheckUtils类中main方法中的实例使用,如需要修改(如需要获取延长线上的交点
修改getIntersectPoint()方法中加----的地方即可),查看代码中发注释修改代码即可。

如果发现问题可以在下面留言讨论。

一、获取两条经纬度线段的交点坐标工具类

package cn.wys.utils;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** @program: Wys* @description 获取两条经纬度线段的交点坐标工具类* @author: wys* @create: 2020-11-27 09:21**/
public class GisCheckUtils {private static Logger log = LoggerFactory.getLogger(GisCheckUtils.class);/*** 地球周长*/private static double L = 6381372 * Math.PI * 2;/*** 平面展开后,x轴等于周长*/private static double W = L;/*** y轴约等于周长一半*/private static double H = L / 2;/*** 米勒投影中的一个常数,范围大约在正负2.3之间*/private static double mill = 2.3;public static void main(String[] args) {/* 拾取坐标系统 可直接复制坐标测试http://api.map.baidu.com/lbsapi/getpoint/index.html*///线段一SegmentLatLon segmentLatLonOne = new SegmentLatLon();segmentLatLonOne.setStartLatLon(new LatLon(116.393561, 39.940041));segmentLatLonOne.setEndLatLon(new LatLon(116.400172, 39.953704));//线段二SegmentLatLon segmentLatLonTwo = new SegmentLatLon();segmentLatLonTwo.setStartLatLon(new LatLon(116.37387, 39.946569));segmentLatLonTwo.setEndLatLon(new LatLon(116.402288,39.943856));//判断是否相交(延长线相交不算)boolean b = segIntersect(segmentLatLonOne, segmentLatLonTwo);log.info("判断是否相交: " + b);//交点坐标(延长线相交不算)LatLon intersectPoint = getIntersectPoint(segmentLatLonOne, segmentLatLonTwo);log.info("交点坐标:" + intersectPoint);}/*** 将经纬度转换成X和Y轴* 米勒投影算法** @param lat 纬度* @param lon 经度* @return*/private static Point millierConvertion(double lat, double lon) {// 将经度从度数转换为弧度double x = lon * Math.PI / 180;// 将纬度从度数转换为弧度double y = lat * Math.PI / 180;// 米勒投影的转换y = 1.25 * Math.log(Math.tan(0.25 * Math.PI + 0.4 * y));// 弧度转为实际距离x = (W / 2) + (W / (2 * Math.PI)) * x;y = (H / 2) - (H / (2 * mill)) * y;return new Point(x, y);}/*** xy轴转坐标** @param x* @param y* @return 坐标点*/private static LatLon xyToLatLon(double x, double y) {//实际距离 转为弧度x = (x - (W / 2)) / (W / (2 * Math.PI));y = -1 * (y - (H / 2)) / (H / (2 * mill));// 米勒投影的转换反转y = (Math.atan(Math.pow(Math.E, y / 1.25)) - 0.25 * Math.PI) / 0.4;//将经度从弧度转换为度数double lon = 180 / Math.PI * x;//将纬度从弧度转换为度数double lat = 180 / Math.PI * y;return new LatLon(lon, lat);}/*** 获取两条直线相交的点** @param segmentLatLonOne 线段一* @param segmentLatLonTwo 线段二* @return 相交点坐标  为null 不相交*/public static LatLon getIntersectPoint(SegmentLatLon segmentLatLonOne, SegmentLatLon segmentLatLonTwo) {//先判断有没有相交 (延长线不算) 不相交返回null 相交执行获取交点坐标 (如需获取延长线交点注释此方法)----if (!segIntersect(segmentLatLonOne, segmentLatLonTwo)) {return null;}//----//转换对象Point[] points = segmentLatLonToPoint(segmentLatLonOne, segmentLatLonTwo);//获取两条直线相交的点Point latLon = getIntersectPoint(points[0], points[1], points[2], points[3]);if (latLon != null) {return xyToLatLon(latLon.x, latLon.y);}return null;}/*** 获取两条直线相交的点** @param p1 线段一 开始点* @param p2 线段一 结束点* @param p3 线段二 开始点* @param p4 线段二 结束点* @return*/public static Point getIntersectPoint(Point p1, Point p2, Point p3, Point p4) {double A1 = p1.getY() - p2.getY();double B1 = p2.getX() - p1.getX();double C1 = A1 * p1.getX() + B1 * p1.getY();double A2 = p3.getY() - p4.getY();double B2 = p4.getX() - p3.getX();double C2 = A2 * p3.getX() + B2 * p3.getY();double det_k = A1 * B2 - A2 * B1;if (Math.abs(det_k) < 0.00001) {return null;}double a = B2 / det_k;double b = -1 * B1 / det_k;double c = -1 * A2 / det_k;double d = A1 / det_k;double x = a * C1 + b * C2;double y = c * C1 + d * C2;return new Point(x, y);}/*** 验证两条线有没有相交** @param segmentLatLonOne 线段1* @param segmentLatLonTwo 线段2* @return true 相交*/public static boolean segIntersect(SegmentLatLon segmentLatLonOne, SegmentLatLon segmentLatLonTwo) {//转换对象Point[] points = segmentLatLonToPoint(segmentLatLonOne, segmentLatLonTwo);//验证两条线有没有相交return segIntersect(points[0], points[1], points[2], points[3]) > 0;}/*** 线段转换为点对象** @param segmentLatLonOne 线段一* @param segmentLatLonTwo 线段二* @return 点对象数组*/private static Point[] segmentLatLonToPoint(SegmentLatLon segmentLatLonOne, SegmentLatLon segmentLatLonTwo) {//线段1Double oneStartLat = segmentLatLonOne.getStartLatLon().getLat();Double oneStartLon = segmentLatLonOne.getStartLatLon().getLon();Double oneEndLat = segmentLatLonOne.getEndLatLon().getLat();Double oneEndLon = segmentLatLonOne.getEndLatLon().getLon();// 线段2Double twoStartLat = segmentLatLonTwo.getStartLatLon().getLat();Double twoStartLon = segmentLatLonTwo.getStartLatLon().getLon();Double twoEndLat = segmentLatLonTwo.getEndLatLon().getLat();Double twoEndLon = segmentLatLonTwo.getEndLatLon().getLon();Point[] points = new Point[4];//将经纬度转换成X和Y轴points[0] = millierConvertion(oneStartLat, oneStartLon);points[1] = millierConvertion(oneEndLat, oneEndLon);points[2] = millierConvertion(twoStartLat, twoStartLon);points[3] = millierConvertion(twoEndLat, twoEndLon);return points;}/*** 验证两条线有没有相交** @param A 线段一 开始点* @param B 线段一 结束点* @param C 线段二 开始点* @param D 线段二 结束点* @return*/public static int segIntersect(Point A, Point B, Point C, Point D) {Point intersection = new Point();if (Math.abs(B.getY() - A.getY()) + Math.abs(B.getX() - A.getX()) + Math.abs(D.getY() - C.getY())+ Math.abs(D.getX() - C.getX()) == 0) {if ((C.getX() - A.getX()) + (C.getY() - A.getY()) == 0) {log.info("ABCD是同一个点!");} else {log.info("AB是一个点,CD是一个点,且AC不同!");}return 0;}if (Math.abs(B.getY() - A.getY()) + Math.abs(B.getX() - A.getX()) == 0) {if ((A.getX() - D.getX()) * (C.getY() - D.getY()) - (A.getY() - D.getY()) * (C.getX() - D.getX()) == 0) {log.info("A、B是一个点,且在CD线段上!");} else {log.info("A、B是一个点,且不在CD线段上!");}return 0;}if (Math.abs(D.getY() - C.getY()) + Math.abs(D.getX() - C.getX()) == 0) {if ((D.getX() - B.getX()) * (A.getY() - B.getY()) - (D.getY() - B.getY()) * (A.getX() - B.getX()) == 0) {log.info("C、D是一个点,且在AB线段上!");} else {log.info("C、D是一个点,且不在AB线段上!");}return 0;}if ((B.getY() - A.getY()) * (C.getX() - D.getX()) - (B.getX() - A.getX()) * (C.getY() - D.getY()) == 0) {log.info("线段平行,无交点!");return 0;}intersection.setX(((B.getX() - A.getX()) * (C.getX() - D.getX())* (C.getY() - A.getY()) - C.getX()* (B.getX() - A.getX()) * (C.getY() - D.getY()) + A.getX() * (B.getY() - A.getY()) * (C.getX() - D.getX()))/ ((B.getY() - A.getY()) * (C.getX() - D.getX()) - (B.getX() - A.getX()) * (C.getY() - D.getY())));intersection.setY(((B.getY() - A.getY()) * (C.getY() - D.getY())* (C.getX() - A.getX()) - C.getY()* (B.getY() - A.getY()) * (C.getX() - D.getX()) + A.getY() * (B.getX() - A.getX()) * (C.getY() - D.getY()))/ ((B.getX() - A.getX()) * (C.getY() - D.getY()) - (B.getY() - A.getY()) * (C.getX() - D.getX())));if ((intersection.getX() - A.getX()) * (intersection.getX() - B.getX()) <= 0&& (intersection.getX() - C.getX())* (intersection.getX() - D.getX()) <= 0&& (intersection.getY() - A.getY())* (intersection.getY() - B.getY()) <= 0&& (intersection.getY() - C.getY())* (intersection.getY() - D.getY()) <= 0) {if ((A.getX() == C.getX() && A.getY() == C.getY()) || (A.getX() == D.getX() && A.getY() == D.getY())|| (B.getX() == C.getX() && B.getY() == C.getY()) || (B.getX() == D.getX() && B.getY() == D.getY())) {log.info("线段相交于端点上");return 2;} else {log.info("线段相交于点(" + intersection.getX() + ","+ intersection.getY() + ")!");//相交return 1;}} else {log.info("线段相交于虚交点(" + intersection.getX() + ","+ intersection.getY() + ")!");//相交但不在线段上return -1;}}/*** 点对象*/public static class Point {private double x;private double y;public Point() {}public Point(double x, double y) {this.x = x;this.y = y;}@Overridepublic String toString() {return  x  + ","+ y ;}public double getX() {return x;}public void setX(double x) {this.x = x;}public double getY() {return y;}public void setY(double y) {this.y = y;}}
}

二、线段坐标实体

package cn.wys.core;/*** @program: Wys* @description 线段坐标实体* @author: wys* @create: 2020-11-27 10:44**/
public class SegmentLatLon {/*** 开始点的坐标*/private LatLon startLatLon;/*** 结束点的坐标*/private LatLon endLatLon;public SegmentLatLon(LatLon startLatLon, LatLon endLatLon) {this.startLatLon = startLatLon;this.endLatLon = endLatLon;}public SegmentLatLon() {}public LatLon getStartLatLon() {return startLatLon;}public void setStartLatLon(LatLon startLatLon) {this.startLatLon = startLatLon;}public LatLon getEndLatLon() {return endLatLon;}public void setEndLatLon(LatLon endLatLon) {this.endLatLon = endLatLon;}
}

三、经纬度实体

package cn.wys.core;/*** @program: Wys* @description 经纬度实体* @author: wys* @create: 2020-11-26 10:44**/
public class LatLon {/*** 经度*/private Double lon;/*** 纬度*/private Double lat;public LatLon() {}public LatLon(Double lon, Double lat) {this.lon = lon;this.lat = lat;}public Double getLon() {return lon;}public void setLon(Double lon) {this.lon = lon;}public Double getLat() {return lat;}public void setLat(Double lat) {this.lat = lat;}@Overridepublic String toString() {return lon +"," + lat ;}
}

对您有帮助的话点个赞吧,谢谢。

java 获取两条经纬度线段的交点坐标工具类相关推荐

  1. java根据两条直线的四个坐标点证明这两条线平行(计算直线斜率)或者三个点在一条直线上

    第一步:原理: 1.若两条直线斜率存在,则:斜率相等,则这两直线平行; 2.若两条直线斜率都不存在,则这两条直线也平行.所以说,如果两条直线平行,则它们的斜率相等[是错误的] 反过来:若两直线斜率相等 ...

  2. JAVA获取N个工作日后的时间的工具类、考虑上班时间、时区

    DayWorkTime代表工作时间描述类 HolidayUtils是计算时间的工具类,addSecondByWorkDay用于计算时间加上指定秒后的工作时间,会自动跳过周末.节假日等.其中holida ...

  3. java获取两个字符串日期之间间隔的天数

    java获取两个字符串日期之间间隔的天数 import java.text.ParseException; import java.text.SimpleDateFormat; import java ...

  4. Java - 计算两个经纬度之间的直线距离

    Java - 计算两个经纬度之间的直线距离 代码Github地址 https://github.com/FrankZuozuo/JavaSpecial 1.点接口 public interface P ...

  5. REVIT建模步骤中:绘制形状不能拾取两条参照平面的交点解决方法

    REVIT建模步骤中:绘制形状不能拾取两条参照平面的交点解决方法 问题:建筑形状(如图-1)所示,当需要在斜面上或者南北立面上绘制形状时,需要设置工作平面,但是在设置好的工作平面中绘制形状时却不能拾取 ...

  6. java计算两个经纬度之间的距离

    前一阵项目中,有一个需求:是查找附近的人,其实就是查询某个距离内有多少用户.实现方式还是比较简单的,之前使用GeodeticCalculator计算经纬度误差在高德上与腾讯有点偏差,首先用户在APP上 ...

  7. java获取两个日期之间的所有日期(包括开始日期和结束日期)

    java获取两个日期之间的所有日期集合 解决方法: import java.text.SimpleDateFormat; import java.util.ArrayList; import java ...

  8. Java操作大数据量Excel导入导出万能工具类(完整版)

    Java操作大数据量Excel导入导出万能工具类(完整版) 转载自:https://blog.csdn.net/JavaWebRookie/article/details/80843653 更新日志: ...

  9. java 中间容器 表格_【JAVA SE基础篇】45.迭代器、Collections工具类以及使用容器存储表格...

    本文将要为您介绍的是[JAVA SE基础篇]45.迭代器.Collections工具类以及使用容器存储表格,具体完成步骤: 1.迭代器 迭代器为我们提供了统一遍历容器(List/Map/Set)的方式 ...

最新文章

  1. ABAP程序发送邮件
  2. SpringBoot 应用程序启动过程探秘
  3. java mysql settings_Java中使用MySQL从安装、配置到实际程序测试详解
  4. pymysql 模块 使用目录
  5. leetcode 304. Range Sum Query 2D - Immutable |304. 二维区域和检索 - 矩阵不可变(二维前缀和问题)
  6. java安全——加密
  7. 微信更新对html影响,微信再次大更新 将极大影响用户使用习惯
  8. 服务端高并发分布式架构演进之路(转载,图画的好)
  9. 微信中音乐播放在ios不能自动播放解决
  10. 搜索做成html静态,如何在静态的html里实现搜索功能?
  11. bzoj 3824: [Usaco2014 Dec]Guard Mark【状压dp】
  12. 路飞学城项目之加入购物车接口
  13. Atitit 软件 开发 与互联网发展趋势 与一些原则 潮流就是社区化 o2o 各种服务化 xaas ##--------信息化建设的理念 1.1.兼容性(不同版本与项目兼容性有利
  14. 在线图片编辑器/在线视频剪辑器/网站源码
  15. LoRaWAN协议中文版 第11章 下行ping帧格式(仅Class B)
  16. [程序设计]Java实现解析抖音无水印视频
  17. android系统同时使用wifi和4g上网
  18. 1378:最短路径(shopth)
  19. 高职学校计算机研讨内容,高职院校计算机文化基础课教学与计算机等级考试关系研讨...
  20. 基础算法题——天梯赛座位分配(化繁为简)

热门文章

  1. java中nextint_java中next()、nextInt()、nextLine()区别
  2. 橙知学堂3.0运营思路揭秘-世界500强企业的在线学习平台
  3. C语言简易程序设计————10、输出国际象棋棋盘
  4. 解决HTML四周空白问题
  5. 外贸开发信退信严重,找EmailCamel解决!
  6. 进入PE后打开c盘提示无法访问c文件或目录损坏,且无法读取
  7. 女装搭配的方法,搭配需要注意的地方
  8. 动态照片墙 python 实现_使用Python生成照片墙,利用,python
  9. 前端入行前五年的简易职业规划
  10. 【iOS】present和push