| | |
| | | |
| | | // 将世界坐标转换为屏幕坐标(用于文字显示) |
| | | Point2D.Double worldMid = new Point2D.Double(midX, midY); |
| | | Point2D.Double screenMid = worldToScreen(worldMid); |
| | | Point2D.Double screenMid = new Point2D.Double(); |
| | | originalTransform.transform(worldMid, screenMid); |
| | | |
| | | // 恢复原始变换以绘制文字(固定大小,不随缩放变化) |
| | | g2d.setTransform(new AffineTransform()); |
| | |
| | | |
| | | private void drawCurrentPlannedPath(Graphics2D g2d) { |
| | | double arrowScale = previewSizingEnabled ? 0.5d : 1.0d; |
| | | lujingdraw.drawPlannedPath(g2d, currentPlannedPath, scale, arrowScale); |
| | | |
| | | // 尝试获取地块信息以支持区分作业路径和移动路径,以及绘制内缩边界 |
| | | String boundaryCoords = null; |
| | | String mowingWidth = null; |
| | | String safetyDistance = null; |
| | | String obstaclesCoords = null; |
| | | String mowingPattern = null; |
| | | |
| | | // 从当前地块编号获取地块信息 |
| | | if (currentBoundaryLandNumber != null) { |
| | | Dikuai landData = Dikuai.getDikuai(currentBoundaryLandNumber); |
| | | if (landData != null) { |
| | | boundaryCoords = landData.getBoundaryCoordinates(); |
| | | mowingWidth = landData.getMowingWidth(); |
| | | safetyDistance = landData.getMowingSafetyDistance(); |
| | | mowingPattern = landData.getMowingPattern(); |
| | | |
| | | // 获取障碍物坐标 |
| | | try { |
| | | java.io.File configFile = new java.io.File("Obstacledge.properties"); |
| | | if (configFile.exists()) { |
| | | Obstacledge.ConfigManager manager = new Obstacledge.ConfigManager(); |
| | | if (manager.loadFromFile(configFile.getAbsolutePath())) { |
| | | Obstacledge.Plot plot = manager.getPlotById(currentBoundaryLandNumber.trim()); |
| | | if (plot != null && plot.getObstacles() != null && !plot.getObstacles().isEmpty()) { |
| | | obstaclesCoords = Obstacledge.buildPlannerPayload(plot.getObstacles()); |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | // 忽略障碍物加载错误 |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 如果无法从地块获取边界,尝试使用当前显示的边界 |
| | | if (boundaryCoords == null || boundaryCoords.trim().isEmpty() || "-1".equals(boundaryCoords.trim())) { |
| | | if (currentBoundary != null && !currentBoundary.isEmpty()) { |
| | | StringBuilder sb = new StringBuilder(); |
| | | for (int i = 0; i < currentBoundary.size(); i++) { |
| | | Point2D.Double pt = currentBoundary.get(i); |
| | | if (i > 0) sb.append(";"); |
| | | sb.append(String.format(java.util.Locale.US, "%.3f,%.3f", pt.x, pt.y)); |
| | | } |
| | | boundaryCoords = sb.toString(); |
| | | } |
| | | } |
| | | |
| | | // 转换割草宽度从厘米到米(如果存在) |
| | | if (mowingWidth != null && !mowingWidth.trim().isEmpty() && !"-1".equals(mowingWidth.trim())) { |
| | | try { |
| | | double widthCm = Double.parseDouble(mowingWidth.trim()); |
| | | double widthMeters = widthCm / 100.0; |
| | | mowingWidth = String.format(java.util.Locale.US, "%.3f", widthMeters); |
| | | } catch (NumberFormatException e) { |
| | | // 如果已经是米为单位,保持原值 |
| | | } |
| | | } |
| | | |
| | | // 转换安全距离从厘米到米(如果存在) |
| | | if (safetyDistance != null && !safetyDistance.trim().isEmpty() && !"-1".equals(safetyDistance.trim())) { |
| | | try { |
| | | double distCm = Double.parseDouble(safetyDistance.trim()); |
| | | // 如果值大于100,认为是厘米,需要转换为米 |
| | | if (distCm > 100) { |
| | | double distMeters = distCm / 100.0; |
| | | safetyDistance = String.format(java.util.Locale.US, "%.3f", distMeters); |
| | | } |
| | | } catch (NumberFormatException e) { |
| | | // 如果已经是米为单位,保持原值 |
| | | } |
| | | } |
| | | |
| | | // 调用带地块信息的绘制方法 |
| | | lujingdraw.drawPlannedPath(g2d, currentPlannedPath, scale, arrowScale, |
| | | boundaryCoords, mowingWidth, safetyDistance, obstaclesCoords, mowingPattern); |
| | | } |
| | | |
| | | private void drawCircleSampleMarkers(Graphics2D g2d, List<double[]> markers, double scale) { |
| | |
| | | .append(',') |
| | | .append(formatCoordinate(point.y)); |
| | | if (i < boundary.size() - 1) { |
| | | |
| | | builder.append(';'); |
| | | } |
| | | } |
| | |
| | | this.boundaryPreviewUpdateCallback = callback; |
| | | } |
| | | |
| | | /** |
| | | * 将视图中心对准当前边界的几何中心 |
| | | */ |
| | | public void centerViewOnBoundary() { |
| | | if (currentBoundary == null || currentBoundary.isEmpty()) { |
| | | return; |
| | | } |
| | | |
| | | Rectangle2D.Double bounds = computeBounds(currentBoundary); |
| | | if (bounds != null) { |
| | | fitBoundsToView(bounds); |
| | | } |
| | | } |
| | | } |