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

写在前面

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

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

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

  1. 定义地球半径
	/**
     * 定义地球半径(米)
     */
    private static final double R_EARTH = 6371000;
  1. 定义地球赤道周长
    /**
     * 定义地球赤道周长(米)
     */
    private static final double P_EARTH = 2 * Math.PI * R_EARTH;
  1. 将长度转换为纬度
    /**
     * 将Y轴的长度(米)转换成纬度
     * @param length
     * @return
     */
    public static double parseYLengthToDegree(double length){
        //将length长度转换为度数
        double yDegree = length / P_EARTH * 360;
        return yDegree;
    }
  1. 将长度转换为经度
    根据线段所在纬度,首先计算当前纬度的地球经线长,除以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)

其他形状同理。

总结

上面是我项目用到技术的简单整理,希望可以帮助到大家。

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是一段Matlab代码,可以判断圆形扇形、多边形和椭圆之间是否存在相交情况: ``` % 定义一个圆形 xc = 0; % 圆心横坐标 yc = 0; % 圆心纵坐标 r = 1; % 圆的半径 % 定义一个扇形 theta1 = pi/4; % 扇形起始角度 theta2 = 3*pi/4; % 扇形结束角度 % 定义一个多边形 x = [0 1 1 0]; % 多边形各个顶点的横坐标 y = [0 0 1 1]; % 多边形各个顶点的纵坐标 % 定义一个椭圆形 a = 2; % 椭圆形长轴长度 b = 1; % 椭圆形短轴长度 xc = 2; % 椭圆心横坐标 yc = 1; % 椭圆心纵坐标 % 判断圆形扇形是否相交 if abs(theta2-theta1) < pi disp('圆形扇形相交'); else disp('圆形扇形不相交'); end % 判断圆形和多边形是否相交 if inpolygon(xc,yc,x,y) disp('圆形和多边形相交'); else disp('圆形和多边形不相交'); end % 判断圆形椭圆形是否相交 if ((xc-a)^2/b^2 + yc^2/a^2 <= 1) || ((xc+a)^2/b^2 + yc^2/a^2 <= 1) disp('圆形椭圆形相交'); else disp('圆形椭圆形不相交'); end % 判断扇形和多边形是否相交 if inpolygon(r*cos(theta1:0.01:theta2)+xc,r*sin(theta1:0.01:theta2)+yc,x,y)) disp('扇形和多边形相交'); else disp('扇形和多边形不相交'); end % 判断扇形椭圆形是否相交 if ((xc-a)^2/b^2 + yc^2/a^2 <= 1) || ((xc+a)^2/b^2 + yc^2/a^2 <= 1) if inpolygon(r*cos(theta1:0.01:theta2)+xc,r*sin(theta1:0.01:theta2)+yc,x,y)) disp('扇形椭圆形相交'); else disp('扇形椭圆形不相交'); end else disp('扇形椭圆形不相交'); end % 判断多边形和椭圆形是否相交 if inpolygon(xc-a*cos(theta1:0.01:theta2),yc+b*sin(theta1:0.01:theta2),x,y) || inpolygon(xc+a*cos(theta1:0.01:theta2),yc+b*sin(theta1:0.01:theta2),x,y) disp('多边形和椭圆形相交'); else disp('多边形和椭圆形不相交'); end ``` 这段代码分别定义了一个圆形、一个扇形、一个多边形和一个椭圆形,并且分别判断它们之间是否存在相交情况。其中,判断圆形扇形是否相交、判断圆形和多边形是否相交和判断圆形椭圆形是否相交的方法较为简单,直接利用数学公式进行判断即可;而判断扇形和多边形是否相交、判断扇形椭圆形是否相交和判断多边形和椭圆形是否相交的方法则需要利用Matlab内置函数 `inpolygon` 进行判断
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值