Java地理信息开发-圆形、椭圆、矩形、扇形在地图上的表示方法及相关判断
写在前面
因为项目需要,做了些地理信息的开发工作,主要包括三部分:
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 / P_EARTH * 360;
return yDegree;
}
- 将长度转换为经度
根据线段所在纬度,首先计算当前纬度的地球经线长,除以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 起始角度
* @param eAngle 终止角度
* @param pointsNum 点数
* @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)
其他形状同理。
总结
上面是我项目用到技术的简单整理,希望可以帮助到大家。