826220679@qq.com
17 小时以前 f94b1436d7a28c8e28d010b2cb657ab7c064e353
src/zhuye/MapRenderer.java
@@ -489,10 +489,7 @@
        drawMower(g2d);
        
        // 绘制导航预览速度(如果正在导航预览)
        if (navigationPreviewSpeed > 0 && mower != null && mower.hasValidPosition()) {
            drawNavigationPreviewSpeed(g2d, scale);
        }
        // 已按需求移除:不在割草机图标上方显示速度
        
        // 绘制测量模式(如果激活)
        if (measurementModeActive) {
@@ -564,16 +561,21 @@
        g2d.setFont(labelFont);
        FontMetrics metrics = g2d.getFontMetrics(labelFont);
        
        // 计算文字位置(在割草机图标上方)
        // 计算文字位置(在割草机图标正上方,间隔20像素固定)
        int textWidth = metrics.stringWidth(speedText);
        int textHeight = metrics.getHeight();
        int textX = (int)Math.round(screenPos.x - textWidth / 2.0);
        // 在割草机图标上方,留出一定间距
        // 图标在世界坐标系中的大小约为 48 * 0.8 / scale 米
        // 转换为屏幕像素:图标高度(像素)= (48 * 0.8 / scale) * scale = 48 * 0.8 = 38.4 像素
        double iconSizePixels = 48.0 * 0.8; // 图标在屏幕上的大小(像素)
        int spacing = 8; // 间距(像素)
        int textY = (int)Math.round(screenPos.y - iconSizePixels / 2.0 - spacing - textHeight);
        // 在割草机图标正上方,间隔20像素
        // 从mower对象获取图标在世界坐标系中的半径,然后转换为屏幕像素
        double iconWorldRadius = mower.getWorldRadius(scale);
        double iconSizePixels = Double.isNaN(iconWorldRadius) ? 38.4 : (iconWorldRadius * 2.0 * scale); // 图标在屏幕上的大小(像素)
        int spacing = 20; // 间距(像素)
        // 图标顶部位置 = 图标中心Y - 图标高度/2
        double iconTopY = screenPos.y - iconSizePixels / 2.0;
        // 精确约束:让背景矩形的底边与图标顶部相距固定spacing像素
        // 背景底边 = textY + metrics.getDescent() + 2(矩形下方内边距)
        // 令 背景底边 = iconTopY - spacing,解得:
        int textY = (int)Math.round(iconTopY - spacing - metrics.getDescent() - 2);
        
        // 绘制文字背景(半透明白色,增强可读性)
        g2d.setColor(new Color(255, 255, 255, 200));
@@ -1531,15 +1533,23 @@
        
        // 如果从地块获取到了路径,使用地块的路径;否则使用currentPlannedPath
        List<Point2D.Double> pathToDraw = currentPlannedPath;
        List<Boolean> flags = null;
        if (plannedPathStr != null && !plannedPathStr.trim().isEmpty() && !"-1".equals(plannedPathStr.trim())) {
            // 从地块获取的路径
            pathToDraw = lujingdraw.parsePlannedPath(plannedPathStr);
            // 优先解析带标注格式
            lujingdraw.ParsedPath parsed = lujingdraw.parsePlannedPathWithFlags(plannedPathStr);
            pathToDraw = parsed.points;
            flags = parsed.isMowingFlags;
        }
        // 调用带地块信息的绘制方法
        // 调用带地块信息的绘制方法(如有标注优先使用)
        if (pathToDraw != null && pathToDraw.size() >= 2) {
            lujingdraw.drawPlannedPath(g2d, pathToDraw, scale, arrowScale,
                                   boundaryCoords, mowingWidth, safetyDistance, obstaclesCoords, mowingPattern);
            if (flags != null && flags.size() == pathToDraw.size() - 1) {
                lujingdraw.drawPlannedPath(g2d, pathToDraw, flags, scale, arrowScale,
                        boundaryCoords, mowingWidth, safetyDistance, obstaclesCoords, mowingPattern);
            } else {
                lujingdraw.drawPlannedPath(g2d, pathToDraw, scale, arrowScale,
                        boundaryCoords, mowingWidth, safetyDistance, obstaclesCoords, mowingPattern);
            }
        }
    }