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

时间:2025-04-02 17:19:02


import ;
import ;

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 = ();
    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 = (size-1).getLon().doubleValue() *  / 180;
          LowY = (size-1).getLat().doubleValue() *  / 180;
          MiddleX =(0).getLon().doubleValue() *  / 180;
          MiddleY = (0).getLat().doubleValue() *  / 180;
          HighX = (1).getLon().doubleValue() *  / 180;
          HighY = (1).getLat().doubleValue() *  / 180;
        } else if (i == size - 1) {
          LowX = (size-2).getLon().doubleValue() *  / 180;
          LowY = (size-2).getLat().doubleValue() *  / 180;
          MiddleX =(size-1).getLon().doubleValue() *  / 180;
          MiddleY = (size-1).getLat().doubleValue() *  / 180;
          HighX = (0).getLon().doubleValue() *  / 180;
          HighY = (0).getLat().doubleValue() *  / 180;
        } else {
          LowX = (i-1).getLon().doubleValue() *  / 180;
          LowY = (i-1).getLat().doubleValue() *  / 180;
          MiddleX = (i).getLon().doubleValue() *  / 180;
          MiddleY = (i).getLat().doubleValue() *  / 180;
          HighX = (i+1).getLon().doubleValue() *  / 180;
          HighY = (i+1).getLat().doubleValue() *  / 180;
        }

        AM = (MiddleY) * (MiddleX);
        BM = (MiddleY) * (MiddleX);
        CM = (MiddleY);
        AL = (LowY) * (LowX);
        BL = (LowY) * (LowX);
        CL = (LowY);
        AH = (HighY) * (HighX);
        BH = (HighY) * (HighX);
        CH = (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) / (
                (AHtangent * AHtangent + BHtangent * BHtangent + CHtangent * CHtangent)
                        * (ALtangent * ALtangent + BLtangent * BLtangent
                        + CLtangent * CLtangent));

        AngleCos = (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*-AngleCos;
        }
      }
      if (Sum1 > Sum2) {
        Sum = Sum1 + (2 *  * Count2 - Sum2);
      } else {
        Sum = (2 *  * Count1 - Sum1) + Sum2;
      }
      //平方米
      area = (Sum - (size - 2) * ) * Radius * Radius;
    }
    return (area);
  }

}

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