地理信息-圆形、椭圆、扇形的表示方法及相关判断

地理信息-圆形、椭圆、扇形的表示方法及相关判断
强烈推介IDEA2021.1.3破解激活,IntelliJ IDEA 注册码,2021.1.3IDEA 激活码 

大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说地理信息-圆形、椭圆、扇形的表示方法及相关判断,希望能够帮助大家进步!!!

目录

写在前面

一、长度(米)转换为经纬度

二、将圆形、椭圆、扇形用Geometry对象表示

表示圆形

表示椭圆

 

表示扇形

效果展示

三、判断线段与图形是否相交


写在前面

因为项目需要,做了些地理信息的开发工作,主要包括三部分:
1、将长度(米)转换成经纬度的度数;
2、将圆形、椭圆、矩形、扇形用Java对象表示:用到com.vividsolutions.jts.util.GeometricShapeFactory工厂类和com.vividsolutions.jts.geom.Geometry对象;
3、判断线段与上述图形在地图上是否相交。

一、长度(米)转换为经纬度

长度和经纬度转换中,纬度转换容易,因为所有纬线等长,可是不同位置经线长度不同,导致不同位置经度转换不同。下面我整理经度和纬度转换两种方式:
在这里插入图片描述

  • 定义地球半径
/** * 定义地球半径(米) */ private static final double R_EARTH = 6371000;
  • 定义地球赤道周长
 /** * 定义地球赤道周长(米) */ private static final double P_EARTH = 2 * Math.PI * R_EARTH;
  • 将长度转换为纬度
 /** * 将Y轴的长度(米)转换成纬度 * @param length * @return */ public static double parseYLengthToDegree(double length){ //这种方式不对 半径会偏长 //将length长度转换为度数
// double yDegree = length / EARTH_RADIUS * 360;
// return yDegree; //使用Y轴做计量 会形成一个椭圆弧 这里在X轴也组处理暂时 没有找到方案 Double degree = ((2 * Math.PI * 3959 ) * 1609) / 360.0; Double dpmLat = 1 / degree; Double radiusLat = dpmLat * length; return radiusLat; }
  • 将长度转换为经度
    根据线段所在纬度,首先计算当前纬度的地球经线长,除以360得出每度经线的长度,即可将长度转换为经度。
 /** * 根据所在纬度,将X轴的长度(米)转换成经度 * (因为不同纬度下,1°经度代表的长度不同) * @param y 所在纬度 * @param length 线段长度 * @return */ public static double parseXLengthToDegree(double y,double length){ //将角度(纬度)转换为弧度 double latRadian = Math.toRadians(y); //计算当前纬度地球周长 double latPEarth = P_EARTH * Math.cos(latRadian); //将length长度转换为度数 double xDegree = length / latPEarth * 360; return xDegree; }

二、将圆形、椭圆、扇形用Geometry对象表示

  • 表示圆形

输入参数为中心点的经纬度、半径(米),先将半径转换为经纬度单位,使用com.vividsolutions.jts.util包,生成GeometricShapeFactory工厂类对象,设置相应参数,生成Geometry圆形对象。

import com.vividsolutions.jts.geom.*;	import com.vividsolutions.jts.util.GeometricShapeFactory; /** * 根据圆形中心点经纬度、半径生成圆形(类圆形,32边多边形) * @param x 中心点经度 * @param y 中心点纬度 * @param radius 半径(米) * @return */ public static Polygon createCircle(double x, double y, final double radius) { //将半径转换为度数 double radiusDegree = parseYLengthToDegree(radius); //生成工厂类	private static GeometricShapeFactory shapeFactory = new GeometricShapeFactory();	//设置生成的类圆形边数 shapeFactory.setNumPoints(32); //设置圆形中心点经纬度 shapeFactory.setCentre(new Coordinate(x, y)); //设置圆形直径 shapeFactory.setSize(radiusDegree * 2); //使用工厂类生成圆形 Polygon circle = shapeFactory.createCircle(); return circle; }

 

  • 表示椭圆

输入参数为:中心点经纬度、长轴长度(米)、短轴长度(米)、长轴和X轴夹角(度)。
首先将长轴和短轴转换为经纬度,
然后将夹角转换为弧度,
为GeometricShapeFactory工厂类设置相关属性,生成Geometry椭圆对象。

 /** * 根据中心点经纬度、长轴、短轴、角度生成椭圆 * @param x * @param y * @param macroaxis * @param brachyaxis * @param direction * @return */ public static Polygon createEllipse(double x,double y,double macroaxis,double brachyaxis,double direction){ //将长短轴转换为度数 double macroaxisDegree = parseYLengthToDegree(macroaxis); double brachyaxisDegree = parseYLengthToDegree(brachyaxis); //将夹角转换为弧度 double radians = Math.toRadians(direction); //设置中心点 shapeFactory.setCentre(new Coordinate(x,y)); //设置长轴长度 shapeFactory.setWidth(macroaxisDegree); //设置短轴长度 shapeFactory.setHeight(brachyaxisDegree); //设置长轴和X轴夹角 shapeFactory.setRotation(radians); //生成椭圆对象 Polygon ellipse = shapeFactory.createEllipse(); return ellipse; }

  • 表示扇形

输入参数:中心点经纬度、扇形半径(米)、起始角度、终止角度;
首先将半径转换为经纬度度数,
然后将起始角度和终止角度转换为弧度,
为GeometricShapeFactory工厂类设置相关属性,生成Geometry扇形对象。

 /** * 根据中心点经纬度、半径、起止角度生成扇形 * @param x 经度 * @param y 纬度 * @param radius 半径(公里) * @param bAngle 起始角度(X轴正方向为0度,逆时针旋转) * @param eAngle 终止角度 * @param pointsNum 点数(往上参考可以给32) * @return */ public static Polygon createSector(double x,double y,double radius,double bAngle,double eAngle,int pointsNum){ //将半径转换为度数 double radiusDegree = parseYLengthToDegree(radius); //将起始角度转换为弧度 double bAngleRadian = Math.toRadians(bAngle); //将终止角度-起始角度计算扇形夹角 double angleRadian = Math.toRadians((eAngle - bAngle + 360) % 360); //设置点数 shapeFactory.setNumPoints(pointsNum); //设置中心点经纬度 shapeFactory.setCentre(new Coordinate(x, y)); //设置直径 shapeFactory.setSize(radiusDegree * 2); //传入起始角度和扇形夹角,生成扇形 Polygon sector = shapeFactory.createArcPolygon(bAngleRadian,angleRadian); return sector; }

效果展示

椭圆
圆形
扇形

三、判断线段与图形是否相交

先创建一个线段对象:

String lineStr = "LINESTRING(123.22 35.22,127.32 38.23)";
WKTReader wktReader = new WKTReader();
LineString line = (LineString) wktReader.read(strLine);

然后通过线段对象的方法来判断:

//判断线段是否包含在椭圆中
line.within(ellipse)
//判断线段与椭圆是否相交
line.crosses(ellipse)

其他形状同理。

本文来源huayang183,由架构君转载发布,观点不代表Java架构师必看的立场,转载请标明来源出处:https://javajgs.com/archives/18035

发表评论