package bianjie;
|
|
import java.util.List;
|
|
import zhuye.Coordinate;
|
|
public class jisuanmianjie {
|
/**
|
* 计算coordinates集合中所有经纬度点围成的多边形面积
|
* 使用球面多边形面积计算公式,适用于经纬度坐标
|
*
|
* @return 多边形面积(平方米)
|
*/
|
public static double calculatePolygonArea() {
|
List<Coordinate> coordinates =Coordinate.coordinates;
|
if (coordinates == null || coordinates.size() < 3) {
|
System.err.println("坐标点数量不足,至少需要3个点才能构成多边形");
|
return 0.0;
|
}
|
|
int pointCount = coordinates.size();
|
double totalArea = 0.0;
|
final double EARTH_RADIUS = 6371000.0; // 地球半径(米)
|
|
try {
|
// 将度分格式转换为十进制度
|
double[] lats = new double[pointCount];
|
double[] lons = new double[pointCount];
|
|
for (int i = 0; i < pointCount; i++) {
|
Coordinate coord = coordinates.get(i);
|
lats[i] = parseDMMToDegree(coord.getLatitude(), coord.getLatDirection());
|
lons[i] = parseDMMToDegree(coord.getLongitude(), coord.getLonDirection());
|
}
|
|
// 使用球面多边形面积公式
|
for (int i = 0; i < pointCount; i++) {
|
int j = (i + 1) % pointCount;
|
|
double lat1 = Math.toRadians(lats[i]);
|
double lon1 = Math.toRadians(lons[i]);
|
double lat2 = Math.toRadians(lats[j]);
|
double lon2 = Math.toRadians(lons[j]);
|
|
totalArea += (lon2 - lon1) * (2 + Math.sin(lat1) + Math.sin(lat2));
|
}
|
|
totalArea = totalArea * EARTH_RADIUS * EARTH_RADIUS / 2.0;
|
|
// 取绝对值确保面积为正
|
return Math.abs(totalArea);
|
|
} catch (Exception e) {
|
System.err.println("计算多边形面积时发生错误: " + e.getMessage());
|
e.printStackTrace();
|
return 0.0;
|
}
|
}
|
|
/**
|
* 将度分格式转换为十进制度
|
* 格式示例:纬度"3956.1234" + 方向"N" -> 39.93539度
|
*
|
* @param dmm 度分格式字符串
|
* @param direction 方向(N/S/E/W)
|
* @return 十进制度
|
*/
|
private static double parseDMMToDegree(String dmm, String direction) {
|
if (dmm == null || dmm.isEmpty()) {
|
return 0.0;
|
}
|
|
try {
|
// 找到小数点的位置
|
int dotIndex = dmm.indexOf('.');
|
if (dotIndex == -1) {
|
dotIndex = dmm.length();
|
}
|
|
// 确保有足够的位数
|
if (dotIndex < 2) {
|
return 0.0;
|
}
|
|
// 提取度和分
|
int degrees = Integer.parseInt(dmm.substring(0, dotIndex - 2));
|
double minutes = Double.parseDouble(dmm.substring(dotIndex - 2));
|
|
// 转换为十进制度
|
double decimalDegrees = degrees + minutes / 60.0;
|
|
// 根据方向调整符号
|
if ("S".equalsIgnoreCase(direction) || "W".equalsIgnoreCase(direction)) {
|
decimalDegrees = -decimalDegrees;
|
}
|
|
return decimalDegrees;
|
|
} catch (NumberFormatException e) {
|
System.err.println("坐标格式转换错误: " + dmm);
|
return 0.0;
|
}
|
}
|
|
/**
|
* 计算面积并返回带单位的字符串
|
*
|
* @return 面积字符串(平方米和亩)
|
*/
|
public static String getAreaString() {
|
double areaM2 = calculatePolygonArea();
|
double areaMu = areaM2 / 666.67; // 转换为亩(1亩 ≈ 666.67平方米)
|
|
return String.format("面积: %.2f 平方米 (约 %.2f 亩)", areaM2, areaMu);
|
}
|
|
/**
|
* 计算面积并返回带单位的字符串(指定小数位数)
|
*
|
* @param decimalPlaces 小数位数
|
* @return 面积字符串(平方米和亩)
|
*/
|
public static String getAreaString(int decimalPlaces) {
|
double areaM2 = calculatePolygonArea();
|
double areaMu = areaM2 / 666.67;
|
|
String format = "面积: %." + decimalPlaces + "f 平方米 (约 %." + decimalPlaces + "f 亩)";
|
return String.format(format, areaM2, areaMu);
|
}
|
}
|