| | |
| | | // 高级处理边界数据方法 |
| | | public List<Coordinate> processBoundaryDataAdvanced(String gnggaData, double baseLat, double baseLon, |
| | | BoundaryParameters params) { |
| | | System.out.println("开始处理边界数据..."); |
| | | System.out.println("基准站坐标: " + baseLat + ", " + baseLon); |
| | | System.out.println("参数: 间隔=" + params.interval + "米, 角度阈值=" + params.angleThreshold + "度"); |
| | | |
| | | // 1. 解析GNGGA数据 |
| | | List<Coordinate> rawPoints = parseGNGGA(gnggaData, baseLat, baseLon); |
| | | System.out.println("解析到原始点: " + rawPoints.size() + " 个"); |
| | | |
| | | if (rawPoints.size() < 3) { |
| | | System.out.println("数据点不足,无法形成边界"); |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | // 2. 过滤和平滑数据 |
| | | List<Coordinate> filteredPoints = filterAndSmoothPoints(rawPoints); |
| | | System.out.println("过滤后点: " + filteredPoints.size() + " 个"); |
| | | |
| | | // 3. 高级边界点优化 |
| | | List<Coordinate> optimizedPoints = optimizeBoundaryPointsAdvanced(filteredPoints, params); |
| | | System.out.println("优化后边界点: " + optimizedPoints.size() + " 个"); |
| | | |
| | | // 4. 边界质量评估 |
| | | BoundaryQuality quality = evaluateBoundaryQuality(optimizedPoints); |
| | | System.out.println(quality.toString()); |
| | | |
| | | return optimizedPoints; |
| | | } |
| | |
| | | // 5. 自动选择预设场景 |
| | | selectPresetAutomatically(analysis); |
| | | |
| | | System.out.println(analysis.toString()); |
| | | return analysis; |
| | | } |
| | | |
| | |
| | | } else { |
| | | analysis.suggestedPreset = "复杂小区域"; |
| | | } |
| | | |
| | | System.out.println("自动场景选择得分: " + String.format("%.2f", score) + " -> " + analysis.suggestedPreset); |
| | | } |
| | | |
| | | // 根据场景名称获取参数 |
| | |
| | | } |
| | | |
| | | String[] records = gnggaData.split("\\$GNGGA"); |
| | | System.out.println("找到GNGGA记录: " + (records.length - 1) + " 条"); |
| | | |
| | | for (String record : records) { |
| | | try { |
| | |
| | | |
| | | String[] fields = trimmedRecord.split(","); |
| | | if (fields.length < 7) { |
| | | System.out.println("记录字段不足: " + trimmedRecord); |
| | | continue; |
| | | } |
| | | |
| | |
| | | try { |
| | | fixStatus = Integer.parseInt(fields[6]); |
| | | } catch (NumberFormatException e) { |
| | | System.out.println("定位状态格式错误: " + fields[6]); |
| | | continue; |
| | | } |
| | | |
| | | if (fixStatus != 4) { |
| | | System.out.println("跳过非高精度定位点,状态: " + fixStatus); |
| | | continue; |
| | | } |
| | | |
| | |
| | | double speed = calculateDistance(points.get(i-1), points.get(i)); |
| | | if (speed < 5.0) { // 最大合理速度为5米/秒 |
| | | filtered.add(points.get(i)); |
| | | } else { |
| | | System.out.println("移除高速点: 速度=" + speed + "米/秒"); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | // 1. 首先进行道格拉斯-普克算法简化 |
| | | List<Coordinate> simplified = douglasPeuckerSimplification(points, params.simplificationTolerance); |
| | | System.out.println("道格拉斯-普克简化后: " + simplified.size() + " 个点"); |
| | | |
| | | // 2. 基于距离和角度的进一步优化 |
| | | optimized.add(simplified.get(0)); |
| | |
| | | if (!optimized.get(0).equals(optimized.get(optimized.size() - 1))) { |
| | | Coordinate first = optimized.get(0); |
| | | Coordinate last = optimized.get(optimized.size() - 1); |
| | | double closingDistance = calculateDistance(first, last); |
| | | |
| | | double closingDistance = calculateDistance(last, first); |
| | | |
| | | if (closingDistance > params.interval) { |
| | | // 如果首尾距离较远,添加中间点 |
| | | List<Coordinate> interpolated = interpolateBoundary( |
| | | List.of(last, first), params.interval |
| | | ); |
| | | optimized.addAll(interpolated.subList(1, interpolated.size() - 1)); |
| | | int segments = (int) Math.ceil(closingDistance / params.interval); |
| | | for (int i = 1; i < segments; i++) { |
| | | double ratio = (double) i / segments; |
| | | Coordinate interpolatedPoint = interpolate(last, first, ratio); |
| | | if (!interpolatedPoint.equals(last)) { |
| | | optimized.add(interpolatedPoint); |
| | | } |
| | | } |
| | | } |
| | | optimized.add(first); |
| | | } |
| | | |
| | | return optimized; |
| | | |
| | | return removeConsecutiveDuplicates(optimized); |
| | | } |
| | | |
| | | // 道格拉斯-普克算法 |
| | |
| | | return interpolated; |
| | | } |
| | | |
| | | private List<Coordinate> removeConsecutiveDuplicates(List<Coordinate> points) { |
| | | if (points == null || points.isEmpty()) { |
| | | return points; |
| | | } |
| | | |
| | | List<Coordinate> cleaned = new ArrayList<>(); |
| | | Coordinate previous = null; |
| | | for (Coordinate point : points) { |
| | | if (previous == null || !point.equals(previous)) { |
| | | cleaned.add(point); |
| | | previous = point; |
| | | } |
| | | } |
| | | |
| | | if (!cleaned.isEmpty() && !cleaned.get(0).equals(cleaned.get(cleaned.size() - 1))) { |
| | | cleaned.add(cleaned.get(0)); |
| | | } |
| | | return cleaned; |
| | | } |
| | | |
| | | // 线性插值 |
| | | private Coordinate interpolate(Coordinate p1, Coordinate p2, double ratio) { |
| | | double x = p1.x + (p2.x - p1.x) * ratio; |