增加新的轨迹绘制方法
authorCaisking <Casiking@zhihuishixun.com>
Thu, 22 Jan 2026 08:18:11 +0000 (16:18 +0800)
committerCaisking <Casiking@zhihuishixun.com>
Thu, 22 Jan 2026 08:18:11 +0000 (16:18 +0800)
code/sdk/application/wearable/fd272/nativeapp/nativeui/traing/include/TraingEnddataView.h
code/sdk/application/wearable/fd272/nativeapp/nativeui/traing/src/TraingEnddataView.cpp

index 2d2eb84..226fe24 100644 (file)
@@ -38,6 +38,7 @@
 #include "uicomponents/UIComponents.h"
 
 #include "components/ui_canvas.h"
+#include "components/ui_canvas_ext.h"
 
 
 namespace OHOS {
@@ -81,8 +82,10 @@ public:
   void ExitView();
 
   void GenerateTrackPoints(void);
-  void DrawMarkers(UICanvas *canvas);
-  void DrawTrackSegment(UICanvas *canvas);
+  void DrawMarkers(UICanvas *canvas);  // 原有绘制方法
+  void DrawMarkers(UICanvasExt *canvas);  // 新绘制方法重载
+  void DrawTrackSegment(UICanvas *canvas);  // 原有绘制方法
+  void DrawTrackSegmentWithPolyline(UICanvasExt *canvas);  // 使用DrawPolyline接口的新方法
   void GenerateTestTrackPoints(size_t pointCount = 10000); // 生成测试轨迹点
   // ColorType GetGradientColor(const ColorType &start, const ColorType &end, float progress);
 
@@ -136,7 +139,8 @@ private:
   UIImageView *imageLine11 = nullptr;
   UIImageView *imageLine12 = nullptr;
 
-   UICanvas *canvas = nullptr;
+   UICanvas *canvas = nullptr;  // 原有绘制方法
+   UICanvasExt *canvasExt = nullptr;  // 新绘制方法
 
   bool viewiInitStatus{false};
 
index 5c742c6..0116a50 100644 (file)
@@ -5,6 +5,8 @@
 #include "common/image_cache_manager.h"
 #include "components/ui_button.h"
 #include "components/ui_canvas.h"
+#include "components/ui_canvas_ext.h"
+#include "draw/hw_draw_utils.h"
 #include "components/ui_label.h"
 #include "components/ui_label_ext.h"
 #include "traing/Training_UiConfig.h"
@@ -558,6 +560,14 @@ void TraingEnddataView::DeInit() {
     canvas = nullptr;
   }
 
+  if (canvasExt) {
+    // 清空轨迹数据,确保加载新的数据
+    TraingModel::GetInstance()->ClearCanvasData();
+    trackSegments_.clear();
+    delete canvasExt;
+    canvasExt = nullptr;
+  }
+
     delete scrollView_;
     scrollView_ = nullptr;
   }
@@ -791,15 +801,29 @@ void TraingEnddataView::OnStart() {
 #if defined(SUPPORT_GNSS)
   std::vector<Point> canvasData = TraingModel::GetInstance()->GetCanvasData();
   if (canvasData.size() >= 3) {
+  #if 0
+    // 选择使用原有方法还是新方法:
+    // 方法1:使用原有绘制方法(推荐,稳定可靠)
     canvas = new UICanvas();
     canvas->SetHeight(CANVAS_SIZE);
     canvas->SetWidth(CANVAS_SIZE);
     canvas->SetPosition(33, 100);
     scrollView_->Add(canvas);
     GenerateTrackPoints();
-    // 有足够数据,绘制轨迹
-    DrawTrackSegment(canvas);
+    DrawTrackSegment(canvas);  // 使用原有绘制方法
     DrawMarkers(canvas);
+   #else
+    // 方法2:使用新绘制方法(使用DrawPolyline接口,需要UICanvasExt)
+    // 如需使用新方法,取消下面注释并注释掉上面的方法1代码
+    canvasExt = new UICanvasExt();
+    canvasExt->SetHeight(CANVAS_SIZE);
+    canvasExt->SetWidth(CANVAS_SIZE);
+    canvasExt->SetPosition(33, 100);
+    scrollView_->Add(canvasExt);
+    GenerateTrackPoints();
+    DrawTrackSegmentWithPolyline(canvasExt);  // 使用新绘制方法
+    DrawMarkers(canvasExt);
+    #endif
   } else {
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS轨迹数据不足,不绘制轨迹");
   }
@@ -810,6 +834,43 @@ void TraingEnddataView::OnStart() {
 
 //////////////////////////////gps轨迹测试/////////////////////////////////////
 
+//绘制轨迹接口
+int16_t DrawPolyline(UICanvasExt* canvas, const Point *points, uint32_t pointNum, const PaintExt& paint)
+{
+    if (canvas == nullptr || points == nullptr || pointNum <= 1) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "invalid parameters canvas(%p), points(%p), pointNum(%u).", 
+                      canvas, points, pointNum);
+        return -1;
+    }
+
+    Path* path = new Path();
+    (void)memset_s(path, sizeof(Path), 0, sizeof(Path));
+
+    if (!HWDrawUtils::GetInstance()->AllocBufferForPath(path, pointNum, pointNum * 2)) { // 2: coe
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Alloc buffer for path failed.");
+        delete path;
+        return -1;
+    }
+
+    path->data[0] = points[0].x;
+    path->data[1] = points[0].y;
+    path->cmds[0] = CMD_MOVE_TO;
+    for (uint32_t i = 1; i < pointNum; i++) {
+        path->data[2 * i] = points[i].x; // 2: coe
+        path->data[2 * i + 1] = points[i].y; // 2: coe
+        path->cmds[i] = CMD_LINE_TO;
+    }
+
+    canvas->BeginPath(paint);
+    canvas->SetPathData(pointNum, path->cmds, pointNum * 2, path->data);
+    canvas->DrawPath();
+    
+    // 释放Path对象分配的内存
+    HWDrawUtils::GetInstance()->FreeBufferForPath(path);
+    delete path;
+    return 0;
+}
+
 std::vector<Marker> markers_ = {{{58, 18}, "起", Color::Green()},
                                 {{299, 146}, "终", Color::Red()}};
 
@@ -831,6 +892,7 @@ void TraingEnddataView::GenerateTrackPoints() {
   markers_[0].pos = canvasData[0];
   markers_[1].pos = canvasData.back();
 }
+// 原有绘制方法 - 保留作为备选
 void TraingEnddataView::DrawTrackSegment(UICanvas *canvas) {
   // 绘制网格
   // Paint debugPaint;
@@ -840,7 +902,7 @@ void TraingEnddataView::DrawTrackSegment(UICanvas *canvas) {
   //   canvas->DrawLine({0, i}, {CANVAS_SIZE, i}, debugPaint);
   // }
 
-  // 绘制轨迹
+  // 绘制轨迹 - 原有方法
   for (const auto &seg : trackSegments_) {
     if (seg.points.size() < 3) //至少需要 3 个点位
       return;
@@ -858,6 +920,33 @@ void TraingEnddataView::DrawTrackSegment(UICanvas *canvas) {
     canvas->DrawPath(paint);
   }
 }
+
+// 使用DrawPolyline接口的新绘制方法 - 作为备选方案
+void TraingEnddataView::DrawTrackSegmentWithPolyline(UICanvasExt *canvas) {
+  // 绘制网格
+  // Paint debugPaint;
+  // debugPaint.SetStrokeColor(Color::Gray());
+  // for (int i = 0; i < CANVAS_SIZE; i += 5) {
+  //   canvas->DrawLine({i, 0}, {i, CANVAS_SIZE}, debugPaint);
+  //   canvas->DrawLine({0, i}, {CANVAS_SIZE, i}, debugPaint);
+  // }
+
+  // 绘制轨迹 - 使用DrawPolyline接口
+  for (const auto &seg : trackSegments_) {
+    if (seg.points.size() < 3) //至少需要 3 个点位
+      return;
+
+    // 将Paint转换为PaintExt(PaintExt继承自Paint,可以直接设置属性)
+    PaintExt paintExt;
+    paintExt.SetStyle(Paint::PaintStyle::STROKE_STYLE);
+    paintExt.SetStrokeWidth(8);
+    paintExt.SetStrokeColor(seg.color);
+
+    // 使用DrawPolyline接口一次性绘制所有点
+    DrawPolyline(canvas, seg.points.data(), seg.points.size(), paintExt);
+  }
+}
+// 原有绘制方法 - 使用UICanvas
 void TraingEnddataView::DrawMarkers(UICanvas *canvas) {
   Paint circlePaint;
   circlePaint.SetStyle(Paint::PaintStyle::FILL_STYLE);
@@ -884,4 +973,33 @@ void TraingEnddataView::DrawMarkers(UICanvas *canvas) {
   }
 }
 
+// 新绘制方法重载 - 使用UICanvasExt
+void TraingEnddataView::DrawMarkers(UICanvasExt *canvas) {
+  PaintExt circlePaint;
+  circlePaint.SetStyle(Paint::PaintStyle::FILL_STYLE);
+
+  PaintExt textPaint;
+  textPaint.SetFillColor(Color::White());
+
+  for (const auto &marker : markers_) {
+    // 绘制标记点圆形
+    circlePaint.SetFillColor(marker.color);
+    canvas->DrawCircle(marker.pos, 12, circlePaint);
+
+    // 绘制文字,调整位置和排版
+    UICanvasExt::FontStyle fontStyle;
+    fontStyle.align = TEXT_ALIGNMENT_LEFT; // 文字居左,避免 RTL 反向
+    fontStyle.direct = TEXT_DIRECT_LTR;    // 从左到右排版
+    fontStyle.fontName = DEFAULT_VECTOR_FONT_FILENAME;
+    fontStyle.fontSize = 24; // 适配 300*300 画布
+    fontStyle.letterSpace = 2;
+
+    // 文字位置:圆点右侧偏移,避免覆盖
+    canvas->DrawLabel({marker.pos.x + 18, marker.pos.y - 6}, marker.text, 80,
+                      fontStyle, textPaint);
+  }
+}
+
+
+
 } // namespace OHOS