新需求开发
This commit is contained in:
+388
@@ -0,0 +1,388 @@
|
||||
package org.jeecg.untils;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class CoordinateConverter {
|
||||
|
||||
public static double pi = 3.1415926535897932384626;
|
||||
public static double a = 6378140.0;//1975年国际椭球体长半轴
|
||||
public static double ee = 0.0033528131778969143;//1975年国际椭球体扁率
|
||||
|
||||
/**
|
||||
* 将经纬度转换为度分秒格式或定位地图
|
||||
* @param xy 经纬度字符串,格式如 "116.404,39.915"
|
||||
* @param mode 1-定位地图,其他值-转换为度分秒
|
||||
* @return 转换结果或错误信息
|
||||
*/
|
||||
public String convertToDMS(String xy, int mode) {
|
||||
xy = xy.replace("°", ""); // 删除度符号
|
||||
|
||||
if (!isValidCoordinate(xy)) {
|
||||
return "经纬度错误!请对照检查:\n"
|
||||
+ "不能为空,且必须是数字;\n"
|
||||
+ "经度不能大于179,不能小于-179;\n"
|
||||
+ "纬度不能大于89,不能小于-89。";
|
||||
}
|
||||
|
||||
if (mode == 1) {
|
||||
String[] parts = xy.split(",");
|
||||
double longitude = Double.parseDouble(parts[0]);
|
||||
double latitude = Double.parseDouble(parts[1]);
|
||||
// 这里调用地图定位功能
|
||||
return "已经定位!\n"
|
||||
+ "上述经纬度位于当前地图的中心点\"+\"处,请查阅。\n"
|
||||
+ "若图像不好,可换卫星图。";
|
||||
} else {
|
||||
return "转换结果是:\n" + convertToDegreeMinuteSecond(xy);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否是有效的经纬度
|
||||
*/
|
||||
private boolean isValidCoordinate(String xy) {
|
||||
String[] parts = xy.split(",");
|
||||
if (parts.length != 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
double longitude = Double.parseDouble(parts[0]);
|
||||
double latitude = Double.parseDouble(parts[1]);
|
||||
|
||||
if (Math.abs(longitude) > 179 || Math.abs(latitude) > 89) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将十进制经纬度转换为度分秒格式
|
||||
*/
|
||||
private String convertToDegreeMinuteSecond(String xy) {
|
||||
String[] parts = xy.split(",");
|
||||
double longitude = Double.parseDouble(parts[0]);
|
||||
double latitude = Double.parseDouble(parts[1]);
|
||||
|
||||
String longitudeDMS = decimalToDMS(longitude, true);
|
||||
String latitudeDMS = decimalToDMS(latitude, false);
|
||||
|
||||
return longitudeDMS + "," + latitudeDMS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将十进制转换为度分秒
|
||||
* @param decimal 十进制值
|
||||
* @param isLongitude 是否是经度
|
||||
*/
|
||||
private String decimalToDMS(double decimal, boolean isLongitude) {
|
||||
String direction;
|
||||
if (isLongitude) {
|
||||
direction = decimal >= 0 ? "东经" : "西经";
|
||||
} else {
|
||||
direction = decimal >= 0 ? "北纬" : "南纬";
|
||||
}
|
||||
|
||||
decimal = Math.abs(decimal);
|
||||
int degrees = (int) decimal;
|
||||
double remaining = (decimal - degrees) * 60;
|
||||
int minutes = (int) remaining;
|
||||
double seconds = (remaining - minutes) * 60;
|
||||
|
||||
return String.format("%s%d°%d'%.3f\"", direction, degrees, minutes, seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将度分秒转换为经纬度或定位地图
|
||||
* @param dms 度分秒字符串,格式如 "东经116°23'14.000",北纬39°54'54.000"
|
||||
* @param mode 1-定位地图,其他值-转换为经纬度
|
||||
* @param isWest 是否是西经
|
||||
* @param isSouth 是否是南纬
|
||||
* @return 转换结果或错误信息
|
||||
*/
|
||||
public String convertToDecimal(String dms, int mode, boolean isWest, boolean isSouth) {
|
||||
dms = dms.replace(",", "\",") + "\"";
|
||||
|
||||
if (!isValidDMS(dms)) {
|
||||
return "度°分'秒\"错误!请对照检查:\n"
|
||||
+ "度、分、秒不能为空,必须是数字,且不能是负数;\n"
|
||||
+ "经°不能大于179,纬°不能大于89;分、秒不能大于、等于60。";
|
||||
}
|
||||
|
||||
String longitudePrefix = isWest ? "西经" : "东经";
|
||||
String latitudePrefix = isSouth ? "南纬" : "北纬";
|
||||
|
||||
String formattedDMS = longitudePrefix + dms.replace(",", "," + latitudePrefix);
|
||||
String decimal = dmsToDecimal(formattedDMS);
|
||||
|
||||
// 格式化小数位数
|
||||
String[] parts = decimal.split(",");
|
||||
double longitude = Double.parseDouble(parts[0].replace("经度", ""));
|
||||
double latitude = Double.parseDouble(parts[1].replace("纬度", ""));
|
||||
|
||||
// 保留6位小数
|
||||
String formattedLongitude = String.format("%.6f", longitude);
|
||||
String formattedLatitude = String.format("%.6f", latitude);
|
||||
String formattedResult = formattedLongitude + "-" + formattedLatitude;
|
||||
|
||||
if (mode == 1) {
|
||||
// 这里调用地图定位功能
|
||||
return "已经定位!\n"
|
||||
+ "上述经纬度位于当前地图的中心点\"+\"处,请查阅。\n"
|
||||
+ "若图像不好,可换卫星图。";
|
||||
} else {
|
||||
return formattedResult;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否是有效的度分秒格式
|
||||
*/
|
||||
private boolean isValidDMS(String dms) {
|
||||
String[] parts = dms.split(",");
|
||||
if (parts.length != 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
String longitude = parts[0];
|
||||
String latitude = parts[1];
|
||||
|
||||
String[] lonParts = longitude.split("[°'\"]");
|
||||
String[] latParts = latitude.split("[°'\"]");
|
||||
|
||||
if (lonParts.length < 3 || latParts.length < 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double lonDegrees = Double.parseDouble(lonParts[0]);
|
||||
double lonMinutes = Double.parseDouble(lonParts[1]);
|
||||
double lonSeconds = Double.parseDouble(lonParts[2]);
|
||||
|
||||
double latDegrees = Double.parseDouble(latParts[0]);
|
||||
double latMinutes = Double.parseDouble(latParts[1]);
|
||||
double latSeconds = Double.parseDouble(latParts[2]);
|
||||
|
||||
if (lonDegrees > 179 || lonDegrees < 0 || latDegrees > 89 || latDegrees < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lonMinutes >= 60 || lonMinutes < 0 || lonSeconds >= 60 || lonSeconds < 0 ||
|
||||
latMinutes >= 60 || latMinutes < 0 || latSeconds >= 60 || latSeconds < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将度分秒转换为十进制
|
||||
*/
|
||||
private String dmsToDecimal(String dms) {
|
||||
String[] parts = dms.split(",");
|
||||
String longitude = parts[0];
|
||||
String latitude = parts[1];
|
||||
|
||||
double lonDecimal = parseDMS(longitude);
|
||||
double latDecimal = parseDMS(latitude);
|
||||
|
||||
// 直接返回未格式化的原始值,由convertToDecimal统一处理格式
|
||||
return lonDecimal + "," + latDecimal;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析度分秒字符串为十进制
|
||||
*/
|
||||
private double parseDMS(String dms) {
|
||||
boolean isNegative = dms.startsWith("西经") || dms.startsWith("南纬");
|
||||
dms = dms.replaceAll("[东经西经北纬南纬]", "");
|
||||
|
||||
String[] parts = dms.split("[°'\"]");
|
||||
double degrees = Double.parseDouble(parts[0]);
|
||||
double minutes = Double.parseDouble(parts[1]);
|
||||
double seconds = Double.parseDouble(parts[2]);
|
||||
|
||||
double decimal = degrees + minutes / 60 + seconds / 3600;
|
||||
return isNegative ? -decimal : decimal;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量转换度分秒坐标为十进制度坐标
|
||||
* @param coordinates 坐标数组,每个元素格式为 "东经E:84°52′15.564″ 北纬N:45°35′53.948″"
|
||||
* @return 转换结果列表
|
||||
*/
|
||||
public List<String> batchConvertToDecimal(String[] coordinates) {
|
||||
List<String> results = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < coordinates.length; i++) {
|
||||
try {
|
||||
String coord = coordinates[i];
|
||||
// 分割经度和纬度
|
||||
String[] parts = coord.split("\t");
|
||||
if (parts.length < 2) {
|
||||
parts = coord.split("\\s+");
|
||||
}
|
||||
|
||||
if (parts.length >= 2) {
|
||||
String dj = parts[0].trim();
|
||||
String bw = parts[1].trim();
|
||||
|
||||
// 清洗数据格式
|
||||
String cleanDj = cleanCoordinateString(dj, true);
|
||||
String cleanBw = cleanCoordinateString(bw, false);
|
||||
|
||||
// 组合成标准DMS格式
|
||||
String dms = cleanDj + "," + cleanBw;
|
||||
|
||||
// 转换并添加到结果列表
|
||||
String result = convertToDecimal(dms, 0, false, false);
|
||||
results.add((i + 1) + ". " + result.replace("转换结果是:\n", ""));
|
||||
} else {
|
||||
results.add((i + 1) + ". 格式错误: " + coord);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
results.add((i + 1) + ". 转换失败: " + coordinates[i] + " - 错误: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清洗坐标字符串
|
||||
*/
|
||||
private String cleanCoordinateString(String coord, boolean isLongitude) {
|
||||
// 替换各种符号为统一格式
|
||||
String cleaned = coord.replace(":", ":")
|
||||
.replace("′", "'")
|
||||
.replace("″", "\"")
|
||||
.replace("‘", "'")
|
||||
.replace("'", "'")
|
||||
.replace("\"", "\"")
|
||||
.replace(" ", "");
|
||||
|
||||
// 移除前缀
|
||||
if (isLongitude) {
|
||||
cleaned = cleaned.replaceAll("[东经E]", "");
|
||||
} else {
|
||||
cleaned = cleaned.replaceAll("[北纬N]", "");
|
||||
}
|
||||
|
||||
// 移除冒号
|
||||
cleaned = cleaned.replace(":", "").trim();
|
||||
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
public String run(String msg){
|
||||
String[] split = msg.split("-");
|
||||
String dj = split[0];
|
||||
String bw = split[1];
|
||||
String cleanDj = dj.replace(":", ":")
|
||||
.replace("′", "'")
|
||||
.replace("″", "\"")
|
||||
.replaceAll("[东经E]", "")
|
||||
.replaceAll("[东经N]", "")
|
||||
.replace(":", "").trim();
|
||||
String cleanBw = bw.replace(":", ":")
|
||||
.replace("′", "'")
|
||||
.replace("″", "\"")
|
||||
.replaceAll("[北纬N]", "")
|
||||
.replaceAll("[北纬E]", "")
|
||||
.replace(":", "").trim();
|
||||
String dms = cleanDj + "," + cleanBw;
|
||||
return convertToDecimal(dms, 0, false, false);
|
||||
}
|
||||
|
||||
|
||||
public static Gps GPS84ToGCJ02(double lon, double lat) {
|
||||
if (outOfChina(lon, lat)) {
|
||||
return null;
|
||||
}
|
||||
double dLat = transformLat(lon - 105.0, lat - 35.0);
|
||||
double dLon = transformLon(lon - 105.0, lat - 35.0);
|
||||
double radLat = lat / 180.0 * pi;
|
||||
double magic = Math.sin(radLat);
|
||||
magic = 1 - ee * magic * magic;
|
||||
double sqrtMagic = Math.sqrt(magic);
|
||||
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
|
||||
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
|
||||
double mgLat = lat + dLat;
|
||||
double mgLon = lon + dLon;
|
||||
return new Gps(mgLon, mgLat);
|
||||
}
|
||||
|
||||
private static boolean outOfChina(double lon, double lat) {
|
||||
if (lon < 72.004 || lon > 137.8347)
|
||||
return true;
|
||||
return lat < 0.8293 || lat > 55.8271;
|
||||
}
|
||||
|
||||
private static double transformLat(double x, double y) {
|
||||
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y
|
||||
+ 0.2 * Math.sqrt(Math.abs(x));
|
||||
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
|
||||
ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
|
||||
ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static double transformLon(double x, double y) {
|
||||
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
|
||||
* Math.sqrt(Math.abs(x));
|
||||
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
|
||||
ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
|
||||
ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0
|
||||
* pi)) * 2.0 / 3.0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static class Gps {
|
||||
private String id;
|
||||
private double longitude;
|
||||
private double latitude;
|
||||
|
||||
public Gps(double lon, double lat) {
|
||||
this.longitude = lon;
|
||||
this.latitude = lat;
|
||||
}
|
||||
|
||||
public Gps() {
|
||||
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public void setLongitude(double longitude) {
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public void setLatitude(double latitude) {
|
||||
this.latitude = latitude;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user