JAVA根据经纬度坐标点集合计算面积



import com.wh.whcloud.common.Location;
import java.util.List;

public class PolygonAreaUtil {

   
/**
 * public class Location {
 *
 *   private BigDecimal lon;
 *
 *   private BigDecimal lat;
 * }
 */

  /**
   * 球面积计算公式
   * @param locationList
   * @return
   */
  public static double calculatePolygonArea(List<Location> locationList) {
    double area = 0;
    int size = locationList.size();
    if (size > 2) {
      double LowX = 0.0;
      double LowY = 0.0;
      double MiddleX = 0.0;
      double MiddleY = 0.0;
      double HighX = 0.0;
      double HighY = 0.0;

      double AM = 0.0;
      double BM = 0.0;
      double CM = 0.0;

      double AL = 0.0;
      double BL = 0.0;
      double CL = 0.0;

      double AH = 0.0;
      double BH = 0.0;
      double CH = 0.0;

      double CoefficientL = 0.0;
      double CoefficientH = 0.0;

      double ALtangent = 0.0;
      double BLtangent = 0.0;
      double CLtangent = 0.0;

      double AHtangent = 0.0;
      double BHtangent = 0.0;
      double CHtangent = 0.0;

      double ANormalLine = 0.0;
      double BNormalLine = 0.0;
      double CNormalLine = 0.0;

      double OrientationValue = 0.0;

      double AngleCos = 0.0;

      double Sum1 = 0.0;
      double Sum2 = 0.0;
      double Count2 = 0;
      double Count1 = 0;

      double Sum = 0.0;
      double Radius = 6378000;

      for (int i = 0; i < size; i++) {
        if (i == 0) {
          LowX = locationList.get(size-1).getLon().doubleValue() * Math.PI / 180;
          LowY = locationList.get(size-1).getLat().doubleValue() * Math.PI / 180;
          MiddleX =locationList.get(0).getLon().doubleValue() * Math.PI / 180;
          MiddleY = locationList.get(0).getLat().doubleValue() * Math.PI / 180;
          HighX = locationList.get(1).getLon().doubleValue() * Math.PI / 180;
          HighY = locationList.get(1).getLat().doubleValue() * Math.PI / 180;
        } else if (i == size - 1) {
          LowX = locationList.get(size-2).getLon().doubleValue() * Math.PI / 180;
          LowY = locationList.get(size-2).getLat().doubleValue() * Math.PI / 180;
          MiddleX =locationList.get(size-1).getLon().doubleValue() * Math.PI / 180;
          MiddleY = locationList.get(size-1).getLat().doubleValue() * Math.PI / 180;
          HighX = locationList.get(0).getLon().doubleValue() * Math.PI / 180;
          HighY = locationList.get(0).getLat().doubleValue() * Math.PI / 180;
        } else {
          LowX = locationList.get(i-1).getLon().doubleValue() * Math.PI / 180;
          LowY = locationList.get(i-1).getLat().doubleValue() * Math.PI / 180;
          MiddleX = locationList.get(i).getLon().doubleValue() * Math.PI / 180;
          MiddleY = locationList.get(i).getLat().doubleValue() * Math.PI / 180;
          HighX = locationList.get(i+1).getLon().doubleValue() * Math.PI / 180;
          HighY = locationList.get(i+1).getLat().doubleValue() * Math.PI / 180;
        }

        AM = Math.cos(MiddleY) * Math.cos(MiddleX);
        BM = Math.cos(MiddleY) * Math.sin(MiddleX);
        CM = Math.sin(MiddleY);
        AL = Math.cos(LowY) * Math.cos(LowX);
        BL = Math.cos(LowY) * Math.sin(LowX);
        CL = Math.sin(LowY);
        AH = Math.cos(HighY) * Math.cos(HighX);
        BH = Math.cos(HighY) * Math.sin(HighX);
        CH = Math.sin(HighY);

        CoefficientL = (AM * AM + BM * BM + CM * CM) / (AM * AL + BM * BL + CM * CL);
        CoefficientH = (AM * AM + BM * BM + CM * CM) / (AM * AH + BM * BH + CM * CH);

        ALtangent = CoefficientL * AL - AM;
        BLtangent = CoefficientL * BL - BM;
        CLtangent = CoefficientL * CL - CM;
        AHtangent = CoefficientH * AH - AM;
        BHtangent = CoefficientH * BH - BM;
        CHtangent = CoefficientH * CH - CM;

        AngleCos = (AHtangent * ALtangent + BHtangent * BLtangent + CHtangent * CLtangent) / (
                Math.sqrt(AHtangent * AHtangent + BHtangent * BHtangent + CHtangent * CHtangent)
                        * Math.sqrt(ALtangent * ALtangent + BLtangent * BLtangent
                        + CLtangent * CLtangent));

        AngleCos = Math.acos(AngleCos);

        ANormalLine = BHtangent * CLtangent - CHtangent * BLtangent;
        BNormalLine = 0 - (AHtangent * CLtangent - CHtangent * ALtangent);
        CNormalLine = AHtangent * BLtangent - BHtangent * ALtangent;

        if (AM != 0) {
          OrientationValue = ANormalLine / AM;
        } else if (BM != 0) {
          OrientationValue = BNormalLine / BM;
        } else {
          OrientationValue = CNormalLine / CM;
        }

        if (OrientationValue > 0) {
          Sum1 += AngleCos;
          Count1++;

        } else {
          Sum2 += AngleCos;
          Count2++;
          //Sum +=2*Math.PI-AngleCos;
        }
      }
      if (Sum1 > Sum2) {
        Sum = Sum1 + (2 * Math.PI * Count2 - Sum2);
      } else {
        Sum = (2 * Math.PI * Count1 - Sum1) + Sum2;
      }
      //平方米
      area = (Sum - (size - 2) * Math.PI) * Radius * Radius;
    }
    return Math.abs(area);
  }

}

区域越不规则的计算会存在误差,如果有伙伴可以解决可以回复下,大家共同学习!

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
项目一Spark离线处理本项目来源于企业级电商网站的大数据统计分析平台,该平台以 Spark 框架为核心,对电商网站的日志进行离线和实时分析。 该大数据分析平台对电商网站的各种用户行为(访问行为、购物行为、广告击行为等)进行分析,根据平台统计出来的数据,辅助公司中的 PM(产品经理)、数据分析师以及管理人员分析现有产品的情况,并根据用户行为分析结果持续改进产品的设计,以及调整公司的战略和业务。最终达到用大数据技术来帮助提升公司的业绩、营业额以及市场占有率的目标。 本项目使用了 Spark 技术生态栈中最常用的三个技术框架,Spark Core、Spark SQL 和 Spark Streaming,进行离线计算和实时计算业务模块的开发。实现了包括用户访问 session 分析、页面单跳转化率统计、热门商品离线统计、广告流量实时统计 4 个业务模块。通过合理的将实际业务模块进行技术整合与改造,该项目几乎完全涵盖了 Spark Core、Spark SQL 和 Spark Streaming 这三个技术框架中大部分的功能、知识,学员对于 Spark 技术框架的理解将会在本项目中得到很大的提高。 项目二Spark实时处理项目简介对于实时性要求高的应用,如用户即时详单查询,业务量监控等,需要应用实时处理架构项目场景对于实时要求高的应用、有对数据进行实时展示和查询需求时项目技术分别使用canal和kafka搭建各自针对业务数据库和用户行为数据的实时数据采集系统,使用SparkStreaming搭建高吞吐的数据实时处理模块,选用ES作为最终的实时数据处理结果的存储位置,并从中获取数据进行展示,进一步降低响应时间。 
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值