package bianjie;
|
import java.util.List;
|
|
public class BoundaryProcessor {
|
|
/**
|
* 处理GNGGA数据并生成优化后的边界坐标
|
*
|
* @param gnggaData GNGGA格式的GPS数据
|
* @param baseStationStr 基站坐标,格式:"纬度,N/S,经度,E/W" 例如:"2324.194945,N,11330.938547,E"
|
* @param interval 边界点间隔(米)
|
* @param angleThreshold 角度阈值(度)
|
* @return 优化后的边界坐标字符串,格式:"X0,Y0;X1,Y1;X2,Y2;..."
|
*/
|
public static String processBoundaryData(String gnggaData, String baseStationStr,
|
double interval, double angleThreshold) {
|
try {
|
// 检查输入数据
|
if (gnggaData == null || gnggaData.trim().isEmpty()) {
|
throw new IllegalArgumentException("GNGGA数据不能为空");
|
}
|
|
if (baseStationStr == null || baseStationStr.trim().isEmpty()) {
|
throw new IllegalArgumentException("基站坐标不能为空");
|
}
|
|
// 解析基准站坐标
|
String[] baseParts = baseStationStr.split(",");
|
if (baseParts.length != 4) {
|
throw new IllegalArgumentException("基准站坐标格式错误,应为: 纬度,N/S,经度,E/W");
|
}
|
|
double baseLat = parseDMCoordinate(baseParts[0], baseParts[1]);
|
double baseLon = parseDMCoordinate(baseParts[2], baseParts[3]);
|
|
// 创建算法实例
|
BoundaryAlgorithm algorithm = new BoundaryAlgorithm();
|
|
// 场景分析
|
BoundaryAlgorithm.SceneAnalysis sceneAnalysis =
|
algorithm.analyzeGNGGAData(gnggaData, baseLat, baseLon);
|
|
// 获取参数(使用场景分析推荐的预设)
|
BoundaryAlgorithm.BoundaryParameters params =
|
algorithm.getParametersForPreset(sceneAnalysis.suggestedPreset);
|
|
// 生成边界
|
List<BoundaryAlgorithm.Coordinate> boundaryPoints =
|
algorithm.processBoundaryDataAdvanced(gnggaData, baseLat, baseLon, params);
|
|
// 质量评估
|
BoundaryAlgorithm.BoundaryQuality boundaryQuality =
|
algorithm.evaluateBoundaryQuality(boundaryPoints);
|
|
// 转换为输出字符串格式
|
return convertBoundaryPointsToString(boundaryPoints);
|
|
} catch (Exception e) {
|
throw new RuntimeException("处理边界数据时发生错误: " + e.getMessage(), e);
|
}
|
}
|
|
/**
|
* 解析度分格式坐标
|
*/
|
private static double parseDMCoordinate(String dmCoord, String direction) {
|
try {
|
if (dmCoord == null || dmCoord.isEmpty()) {
|
return 0;
|
}
|
|
int dotIndex = dmCoord.indexOf('.');
|
if (dotIndex < 2) {
|
return 0;
|
}
|
|
int degrees = Integer.parseInt(dmCoord.substring(0, dotIndex - 2));
|
double minutes = Double.parseDouble(dmCoord.substring(dotIndex - 2));
|
|
double decimal = degrees + minutes / 60.0;
|
|
if ("S".equals(direction) || "W".equals(direction)) {
|
decimal = -decimal;
|
}
|
|
return decimal;
|
} catch (Exception e) {
|
throw new IllegalArgumentException("度分坐标解析错误: " + dmCoord, e);
|
}
|
}
|
|
/**
|
* 将边界点列表转换为字符串格式
|
*/
|
private static String convertBoundaryPointsToString(List<BoundaryAlgorithm.Coordinate> points) {
|
if (points == null || points.isEmpty()) {
|
return "";
|
}
|
|
StringBuilder coordinatesBuilder = new StringBuilder();
|
for (int i = 0; i < points.size(); i++) {
|
BoundaryAlgorithm.Coordinate point = points.get(i);
|
coordinatesBuilder.append(String.format("%.2f,%.2f", point.x, point.y));
|
if (i < points.size() - 1) {
|
coordinatesBuilder.append(";");
|
}
|
}
|
|
return coordinatesBuilder.toString();
|
}
|
|
/**
|
* 高级处理方法 - 允许自定义所有参数
|
*
|
* @param gnggaData GNGGA格式的GPS数据
|
* @param baseStationStr 基站坐标
|
* @param params 边界参数对象
|
* @return 优化后的边界坐标字符串
|
*/
|
public static String processBoundaryDataAdvanced(String gnggaData, String baseStationStr,
|
BoundaryAlgorithm.BoundaryParameters params) {
|
try {
|
// 检查输入数据
|
if (gnggaData == null || gnggaData.trim().isEmpty()) {
|
throw new IllegalArgumentException("GNGGA数据不能为空");
|
}
|
|
if (baseStationStr == null || baseStationStr.trim().isEmpty()) {
|
throw new IllegalArgumentException("基站坐标不能为空");
|
}
|
|
if (params == null) {
|
throw new IllegalArgumentException("边界参数不能为空");
|
}
|
|
// 解析基准站坐标
|
String[] baseParts = baseStationStr.split(",");
|
if (baseParts.length != 4) {
|
throw new IllegalArgumentException("基准站坐标格式错误,应为: 纬度,N/S,经度,E/W");
|
}
|
|
double baseLat = parseDMCoordinate(baseParts[0], baseParts[1]);
|
double baseLon = parseDMCoordinate(baseParts[2], baseParts[3]);
|
|
// 创建算法实例并处理数据
|
BoundaryAlgorithm algorithm = new BoundaryAlgorithm();
|
List<BoundaryAlgorithm.Coordinate> boundaryPoints =
|
algorithm.processBoundaryDataAdvanced(gnggaData, baseLat, baseLon, params);
|
|
// 转换为输出字符串格式
|
return convertBoundaryPointsToString(boundaryPoints);
|
|
} catch (Exception e) {
|
throw new RuntimeException("处理边界数据时发生错误: " + e.getMessage(), e);
|
}
|
}
|
|
/**
|
* 仅进行场景分析,不生成边界
|
*
|
* @param gnggaData GNGGA格式的GPS数据
|
* @param baseStationStr 基站坐标
|
* @return 场景分析结果
|
*/
|
public static BoundaryAlgorithm.SceneAnalysis analyzeScene(String gnggaData, String baseStationStr) {
|
try {
|
// 检查输入数据
|
if (gnggaData == null || gnggaData.trim().isEmpty()) {
|
throw new IllegalArgumentException("GNGGA数据不能为空");
|
}
|
|
if (baseStationStr == null || baseStationStr.trim().isEmpty()) {
|
throw new IllegalArgumentException("基站坐标不能为空");
|
}
|
|
// 解析基准站坐标
|
String[] baseParts = baseStationStr.split(",");
|
if (baseParts.length != 4) {
|
throw new IllegalArgumentException("基准站坐标格式错误,应为: 纬度,N/S,经度,E/W");
|
}
|
|
double baseLat = parseDMCoordinate(baseParts[0], baseParts[1]);
|
double baseLon = parseDMCoordinate(baseParts[2], baseParts[3]);
|
|
// 创建算法实例并进行分析
|
BoundaryAlgorithm algorithm = new BoundaryAlgorithm();
|
return algorithm.analyzeGNGGAData(gnggaData, baseLat, baseLon);
|
|
} catch (Exception e) {
|
throw new RuntimeException("场景分析时发生错误: " + e.getMessage(), e);
|
}
|
}
|
|
/**
|
* 从根目录的properties文件读取GNGGA数据
|
*
|
* @param fileName properties文件名
|
* @return GNGGA格式的GPS数据字符串
|
*/
|
public static String getGNGGAFromProperties(String fileName) {
|
try {
|
// 首先尝试从类路径加载
|
java.io.InputStream input = BoundaryProcessor.class.getClassLoader()
|
.getResourceAsStream(fileName);
|
|
if (input == null) {
|
// 如果类路径没有,尝试从当前工作目录加载
|
java.io.File file = new java.io.File(fileName);
|
if (file.exists()) {
|
input = new java.io.FileInputStream(file);
|
}
|
}
|
|
if (input == null) {
|
throw new RuntimeException("文件未找到: " + fileName);
|
}
|
|
java.util.Properties props = new java.util.Properties();
|
props.load(input);
|
|
// 从properties中获取GNGGA数据
|
String gnggaData = props.getProperty("gngga.data");
|
|
if (gnggaData == null || gnggaData.trim().isEmpty()) {
|
throw new RuntimeException("properties文件中未找到gngga.data属性");
|
}
|
|
input.close();
|
return gnggaData;
|
|
} catch (Exception e) {
|
throw new RuntimeException("读取properties文件时发生错误: " + e.getMessage(), e);
|
}
|
}
|
|
|
}
|