张世豪
6 天以前 c498385fb7e372d13e2ee76d7b54ae2381728082
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
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);
        }
    }
    
  
}