修复GPS轨迹缓存的问题
authorCaisking <Casiking@zhihuishixun.com>
Mon, 12 Jan 2026 11:59:22 +0000 (19:59 +0800)
committerCaisking <Casiking@zhihuishixun.com>
Mon, 12 Jan 2026 11:59:22 +0000 (19:59 +0800)
code/sdk/application/wearable/fd272/nativeapp/nativeui/traing/include/TraingEnddataView.h
code/sdk/application/wearable/fd272/nativeapp/nativeui/traing/src/TraingEnddataView.cpp
code/sdk/application/wearable/fd272/nativeapp/nativeui/traing/src/TraingModel.cpp

index 8741f1a..2d2eb84 100644 (file)
@@ -83,6 +83,7 @@ public:
   void GenerateTrackPoints(void);
   void DrawMarkers(UICanvas *canvas);
   void DrawTrackSegment(UICanvas *canvas);
+  void GenerateTestTrackPoints(size_t pointCount = 10000); // 生成测试轨迹点
   // ColorType GetGradientColor(const ColorType &start, const ColorType &end, float progress);
 
 private:
@@ -140,6 +141,8 @@ private:
   bool viewiInitStatus{false};
 
   std::vector<TrackSegment> trackSegments_;
+  static std::vector<Point> testCanvasData_; // 测试用的canvas数据
+  static bool useTestData_; // 是否使用测试数据
 };
 } // namespace OHOS
 #endif // TraingEnddata_PRESENTER_H
index 096c6cc..895341d 100644 (file)
@@ -554,6 +554,9 @@ void TraingEnddataView::DeInit() {
     delete canvas;
     canvas = nullptr;
   }
+   // 清空轨迹数据,确保加载新的数据
+   TraingModel::GetInstance()->ClearCanvasData();
+   trackSegments_.clear();
 
     delete scrollView_;
     scrollView_ = nullptr;
@@ -730,7 +733,6 @@ void TraingEnddataView::InitData() {
 }
 
 void TraingEnddataView::OnStart() {
-
   bool isNeedGPS = TraingModel::GetInstance()->IsNeedGPS(TraingModel::GetInstance()->GetSportEvent());
   // 判断是否需要GPS
   if (isNeedGPS == true) {
@@ -740,14 +742,22 @@ void TraingEnddataView::OnStart() {
     SportData *enddata = TraingModel::GetInstance()->GetSportdata();
     if (enddata != nullptr) {
       uint32_t startTimestamp = enddata->starttime;
-      std::string gpsFilePath =TraingModel::GetInstance()->GetCanvasDataPath(startTimestamp);
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "加载轨迹图,starttime: %u", startTimestamp);
+      // 确保使用正确的starttime获取对应的GPS文件
+      std::string gpsFilePath = TraingModel::GetInstance()->GetCanvasDataPath(startTimestamp);
       if (!gpsFilePath.empty()) {
+        // 清空旧数据后再加载新数据
+        TraingModel::GetInstance()->ClearCanvasData();
         if (TraingModel::GetInstance()->LoadCanvasData(gpsFilePath) == true) {
-          WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gps文件加载成功");
+          WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gps文件加载成功: %s", gpsFilePath.c_str());
         } else {
-          WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gps文件加载失败");
+          WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gps文件加载失败: %s", gpsFilePath.c_str());
         }
+      } else {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "未找到GPS文件,starttime: %u", startTimestamp);
       }
+    } else {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetSportdata() 返回 nullptr");
     }
 #endif
   }
@@ -759,13 +769,20 @@ void TraingEnddataView::OnStart() {
   scrollView_->SetTouchable(true);
   scrollView_->SetOnDragListener(presenter_);
 
-  // 检查是否有足够的GPS数据来绘制轨迹
-  if (isNeedGPS == false) {
+  // 检查是否有足够的GPS数据来绘制轨迹(测试模式下也允许绘制)
+  if (isNeedGPS == false && !useTestData_) {
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "该运动项不需要GPS");
     return;
   }
-#if defined(SUPPORT_GNSS)
-  std::vector<Point> canvasData = TraingModel::GetInstance()->GetCanvasData();
+#if defined(SUPPORT_GNSS) || defined(TEST_10000_POINTS)
+  std::vector<Point> canvasData;
+  if (useTestData_ && !testCanvasData_.empty()) {
+    canvasData = testCanvasData_;
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "使用测试数据,canvasData.size() = %zu", canvasData.size());
+  } else {
+    canvasData = TraingModel::GetInstance()->GetCanvasData();
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "使用GPS数据,canvasData.size() = %zu", canvasData.size());
+  }
   if (canvasData.size() >= 3) {
     canvas = new UICanvas();
     canvas->SetHeight(CANVAS_SIZE);
@@ -776,6 +793,7 @@ void TraingEnddataView::OnStart() {
     // 有足够数据,绘制轨迹
     DrawTrackSegment(canvas);
     DrawMarkers(canvas);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "轨迹图绘制完成");
   } else {
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS轨迹数据不足,不绘制轨迹");
   }
@@ -789,23 +807,65 @@ void TraingEnddataView::OnStart() {
 std::vector<Marker> markers_ = {{{58, 18}, "起", Color::Green()},
                                 {{299, 146}, "终", Color::Red()}};
 
+// 测试数据
+std::vector<Point> TraingEnddataView::testCanvasData_;
+bool TraingEnddataView::useTestData_ = false;
+
 void TraingEnddataView::GenerateTrackPoints() {
   trackSegments_.clear();
 
   TrackSegment seg1;
   seg1.color = Color::Blue();
 
-  std::vector<Point> canvasData = TraingModel::GetInstance()->GetCanvasData();
+  // 如果使用测试数据,则使用测试数据,否则使用GPS数据
+  std::vector<Point> canvasData;
+  if (useTestData_ && !testCanvasData_.empty()) {
+    canvasData = testCanvasData_;
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "使用测试数据,原始轨迹点数: %zu", canvasData.size());
+  } else {
+    canvasData = TraingModel::GetInstance()->GetCanvasData();
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "使用GPS数据,原始轨迹点数: %zu", canvasData.size());
+  }
+
+  // UICanvas的PathParam.count是uint16_t类型,最大值为65535
+  // 但为了性能和显示效果,我们限制最大绘制点数为300
+  // 对于5小时的跑步(假设18000个点),采样到300个点足够显示轨迹形状
+  const size_t MAX_TRACK_POINTS = 500; // 最大绘制点数,避免点位过多导致轨迹异常和性能问题
+  std::vector<Point> sampledPoints;
+  
+  if (canvasData.size() > MAX_TRACK_POINTS) {
+    // 均匀采样,保留起点和终点
+    sampledPoints.push_back(canvasData[0]); // 起点
+    
+    double step = static_cast<double>(canvasData.size() - 1) / (MAX_TRACK_POINTS - 1);
+    for (size_t i = 1; i < MAX_TRACK_POINTS - 1; ++i) {
+      size_t index = static_cast<size_t>(i * step);
+      if (index < canvasData.size()) {
+        sampledPoints.push_back(canvasData[index]);
+      }
+    }
+    
+    sampledPoints.push_back(canvasData.back()); // 终点
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "采样后轨迹点数: %zu (从 %zu 个点采样,采样率: %.2f%%)", 
+                  sampledPoints.size(), canvasData.size(), 
+                  (sampledPoints.size() * 100.0) / canvasData.size());
+  } else {
+    // 点数不多,直接使用所有点
+    sampledPoints = canvasData;
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "轨迹点数: %zu (无需采样)", sampledPoints.size());
+  }
 
   //将点位赋值
-  for (size_t i = 0; i < canvasData.size(); ++i) {
-    seg1.points.push_back(canvasData[i]);
+  for (size_t i = 0; i < sampledPoints.size(); ++i) {
+    seg1.points.push_back(sampledPoints[i]);
   }
   trackSegments_.push_back(seg1);
 
-  //修改markers_ 起终点坐标
-  markers_[0].pos = canvasData[0];
-  markers_[1].pos = canvasData.back();
+  //修改markers_ 起终点坐标(使用原始数据的起终点,确保标记位置准确)
+  if (!canvasData.empty()) {
+    markers_[0].pos = canvasData[0];
+    markers_[1].pos = canvasData.back();
+  }
 }
 void TraingEnddataView::DrawTrackSegment(UICanvas *canvas) {
   // 绘制网格
@@ -818,7 +878,8 @@ void TraingEnddataView::DrawTrackSegment(UICanvas *canvas) {
 
   // 绘制轨迹
   for (const auto &seg : trackSegments_) {
-    if (seg.points.size() < 3) //至少需要 3 个点位
+    if (seg.points.size() < 3) { //至少需要 3 个点位
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "轨迹点数不足: %zu,无法绘制", seg.points.size());
       return;
 
     Paint paint;
@@ -832,8 +893,47 @@ void TraingEnddataView::DrawTrackSegment(UICanvas *canvas) {
       canvas->LineTo(seg.points[i]);
     }
     canvas->DrawPath(paint);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "轨迹绘制完成,共绘制 %zu 条线段", seg.points.size() - 1);
   }
 }
+}
+void TraingEnddataView::GenerateTestTrackPoints(size_t pointCount) {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "========== 开始生成 %zu 个测试点 ==========", pointCount);
+  
+  // 清空现有测试数据
+  testCanvasData_.clear();
+  testCanvasData_.reserve(pointCount);
+  
+  // 生成模拟轨迹点(螺旋形状,确保轨迹可见)
+  // 画布大小是 CANVAS_SIZE (400),我们生成一个在画布范围内的轨迹
+  const int16_t centerX = CANVAS_SIZE / 2;
+  const int16_t centerY = CANVAS_SIZE / 2;
+  const int16_t maxRadius = CANVAS_SIZE / 2 - 50; // 留出边距
+  
+  for (size_t i = 0; i < pointCount; ++i) {
+    // 生成螺旋轨迹
+    double angle = (i * 2.0 * 3.14159265358979323846) / (pointCount / 4.0); // 4圈螺旋
+    double radius = (maxRadius * i) / pointCount; // 从中心逐渐向外
+    
+    int16_t x = static_cast<int16_t>(centerX + radius * cos(angle));
+    int16_t y = static_cast<int16_t>(centerY + radius * sin(angle));
+    
+    // 确保点在画布范围内
+    if (x < 0) x = 0;
+    if (x >= CANVAS_SIZE) x = CANVAS_SIZE - 1;
+    if (y < 0) y = 0;
+    if (y >= CANVAS_SIZE) y = CANVAS_SIZE - 1;
+    
+    testCanvasData_.push_back({x, y});
+  }
+  
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "生成了 %zu 个测试点", testCanvasData_.size());
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "起点: (%d, %d), 终点: (%d, %d)", 
+                testCanvasData_[0].x, testCanvasData_[0].y, 
+                testCanvasData_.back().x, testCanvasData_.back().y);
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "========== 测试点生成完成 ==========");
+}
+
 void TraingEnddataView::DrawMarkers(UICanvas *canvas) {
   Paint circlePaint;
   circlePaint.SetStyle(Paint::PaintStyle::FILL_STYLE);
index 52c1992..a21bc71 100644 (file)
  // 添加经纬度数据集
  void TraingModel::AddGPSData(uint32_t timestamp, double latitude,
                               double longitude) {
-   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== AddGPSData函数调用开始 ===");
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "=== AddGPSData函数调用开始 ===");
    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
                  "输入参数: timestamp=%u, latitude=%.6f, longitude=%.6f",
                  timestamp, latitude, longitude);
                    lon_diff);
    }
  
-   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== AddGPSData函数调用结束 ===");
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "=== AddGPSData函数调用结束 ===");
  }
  
  //保存canvas数据