| | |
| | | # å²èæºå°åéç¢ç©é
ç½®æä»¶ |
| | | # çææ¶é´ï¼2025-12-25T16:37:39.564155300 |
| | | # çææ¶é´ï¼2025-12-25T19:02:14.286913600 |
| | | # åæ ç³»ï¼WGS84ï¼åº¦åæ ¼å¼ï¼ |
| | | |
| | | # ============ å°ååºåç«é
ç½® ============ |
| | |
| | | #Dikuai Properties |
| | | #Thu Dec 25 16:37:39 CST 2025 |
| | | #Thu Dec 25 19:02:14 CST 2025 |
| | | LAND1.angleThreshold=-1 |
| | | LAND1.baseStationCoordinates=3949.89151752,N,11616.79267501,E |
| | | LAND1.boundaryCoordinates=-58.32,-476.37;85.99,-289.22;354.31,-329.80;293.43,-559.79 |
| | | LAND1.boundaryCoordinates=121.86,-611.32;130.67,-577.12;173.17,-587.48;167.47,-621.17 |
| | | LAND1.boundaryOriginalCoordinates=39.831522,116.279873,49.25;39.831524,116.279878,49.25;39.831525,116.279878,49.24;39.831524,116.279912,49.30;39.831524,116.279911,49.29;39.831523,116.279911,49.23;39.831521,116.279915,49.31;39.831517,116.279925,49.34;39.831514,116.279940,49.30;39.831514,116.279957,49.28;39.831516,116.279974,49.28;39.831518,116.279991,49.29;39.831521,116.280008,49.24;39.831524,116.280025,49.30;39.831526,116.280042,49.24;39.831529,116.280059,49.29;39.831529,116.280076,49.26;39.831530,116.280093,49.32;39.831531,116.280110,49.28;39.831533,116.280127,49.28;39.831535,116.280144,49.26;39.831539,116.280161,49.27;39.831544,116.280175,49.25;39.831551,116.280190,49.24;39.831558,116.280204,49.26;39.831566,116.280219,49.26;39.831574,116.280234,49.22;39.831583,116.280248,49.24;39.831591,116.280260,49.24;39.831600,116.280272,49.23;39.831608,116.280285,49.18;39.831615,116.280298,49.12;39.831618,116.280312,49.11;39.831618,116.280328,49.12;39.831615,116.280342,49.15;39.831610,116.280356,49.21;39.831602,116.280369,49.23;39.831592,116.280379,49.25;39.831581,116.280388,49.25;39.831569,116.280394,49.19;39.831559,116.280395,49.23;39.831552,116.280387,49.28;39.831547,116.280373,49.32;39.831544,116.280357,49.33;39.831541,116.280340,49.29;39.831539,116.280324,49.27;39.831536,116.280307,49.24;39.831534,116.280290,49.25;39.831531,116.280273,49.26;39.831527,116.280257,49.28;39.831522,116.280242,49.21;39.831514,116.280232,49.28;39.831504,116.280229,49.24;39.831491,116.280230,49.33;39.831478,116.280233,49.34;39.831466,116.280236,49.31;39.831454,116.280239,49.31;39.831441,116.280242,49.26;39.831429,116.280244,49.23;39.831416,116.280247,49.25;39.831402,116.280250,49.22;39.831389,116.280253,49.25;39.831376,116.280256,49.26;39.831364,116.280258,49.24;39.831351,116.280261,49.25;39.831338,116.280265,49.26;39.831324,116.280268,49.20;39.831311,116.280271,49.16;39.831298,116.280274,49.17;39.831285,116.280277,49.22;39.831271,116.280278,49.16;39.831261,116.280273,49.23 |
| | | LAND1.boundaryOriginalXY=-1 |
| | | LAND1.boundaryPointInterval=-1 |
| | |
| | | LAND1.mowingPattern=å¹³è¡çº¿ |
| | | LAND1.mowingSafetyDistance=0.53 |
| | | LAND1.mowingTrack=-1 |
| | | LAND1.mowingWidth=500 |
| | | LAND1.mowingWidth=50 |
| | | LAND1.obstacleCoordinates=-1 |
| | | LAND1.plannedPath=353.646421,-330.235669;86.219211,-289.790692;-57.399120,-476.043693;293.049800,-559.155132;353.646421,-330.235669;352.359360,-335.097876;82.727142,-294.319420;79.235073,-298.848147;351.072299,-339.960083;349.785238,-344.822290;75.743005,-303.376874;72.250936,-307.905602;348.498177,-349.684497;347.211116,-354.546703;68.758867,-312.434329;65.266799,-316.963057;345.924055,-359.408910;344.636994,-364.271117;61.774730,-321.491784;58.282661,-326.020511;343.349933,-369.133324;342.062872,-373.995531;54.790593,-330.549239;51.298524,-335.077966;340.775811,-378.857738;339.488750,-383.719945;47.806455,-339.606694;44.314387,-344.135421;338.201689,-388.582152;336.914628,-393.444358;40.822318,-348.664148;37.330249,-353.192876;335.627567,-398.306565;334.340506,-403.168772;33.838181,-357.721603;30.346112,-362.250331;333.053445,-408.030979;331.766384,-412.893186;26.854043,-366.779058;23.361975,-371.307785;330.479324,-417.755393;329.192263,-422.617600;19.869906,-375.836513;16.377837,-380.365240;327.905202,-427.479807;326.618141,-432.342013;12.885769,-384.893968;9.393700,-389.422695;325.331080,-437.204220;324.044019,-442.066427;5.901631,-393.951422;2.409563,-398.480150;322.756958,-446.928634;321.469897,-451.790841;-1.082506,-403.008877;-4.574575,-407.537605;320.182836,-456.653048;318.895775,-461.515255;-8.066643,-412.066332;-11.558712,-416.595059;317.608714,-466.377461;316.321653,-471.239668;-15.050781,-421.123787;-18.542849,-425.652514;315.034592,-476.101875;313.747531,-480.964082;-22.034918,-430.181242;-25.526987,-434.709969;312.460470,-485.826289;311.173409,-490.688496;-29.019055,-439.238696;-32.511124,-443.767424;309.886348,-495.550703;308.599287,-500.412910;-36.003193,-448.296151;-39.495261,-452.824879;307.312226,-505.275116;306.025165,-510.137323;-42.987330,-457.353606;-46.479399,-461.882333;304.738104,-514.999530;303.451043,-519.861737;-49.971467,-466.411061;-53.463536,-470.939788;302.163982,-524.723944;300.876921,-529.586151;-56.955605,-475.468516;-6.018549,-488.228958;299.589860,-534.448358;298.302799,-539.310565;52.837057,-502.186981;111.692662,-516.145005;297.015738,-544.172771;295.728677,-549.034978;170.548268,-530.103028;229.403874,-544.061051;294.441616,-553.897185 |
| | | LAND1.plannedPath=122.510775,-610.918324;167.039920,-620.534901;172.565118,-587.878071;131.052742,-577.758818;122.510775,-610.918324;122.635602,-610.433754;167.123414,-620.041405;167.206909,-619.547910;122.760428,-609.949185;122.885254,-609.464616;167.290403,-619.054415;167.373897,-618.560919;123.010080,-608.980047;123.134906,-608.495477;167.457392,-618.067424;167.540886,-617.573928;123.259733,-608.010908;123.384559,-607.526339;167.624380,-617.080433;167.707875,-616.586937;123.509385,-607.041769;123.634211,-606.557200;167.791369,-616.093442;167.874863,-615.599947;123.759037,-606.072631;123.883864,-605.588061;167.958358,-615.106451;168.041852,-614.612956;124.008690,-605.103492;124.133516,-604.618923;168.125346,-614.119460;168.208841,-613.625965;124.258342,-604.134353;124.383168,-603.649784;168.292335,-613.132470;168.375829,-612.638974;124.507994,-603.165215;124.632821,-602.680645;168.459324,-612.145479;168.542818,-611.651983;124.757647,-602.196076;124.882473,-601.711507;168.626312,-611.158488;168.709807,-610.664993;125.007299,-601.226937;125.132125,-600.742368;168.793301,-610.171497;168.876795,-609.678002;125.256952,-600.257799;125.381778,-599.773229;168.960290,-609.184506;169.043784,-608.691011;125.506604,-599.288660;125.631430,-598.804091;169.127278,-608.197516;169.210773,-607.704020;125.756256,-598.319521;125.881083,-597.834952;169.294267,-607.210525;169.377761,-606.717029;126.005909,-597.350383;126.130735,-596.865813;169.461256,-606.223534;169.544750,-605.730038;126.255561,-596.381244;126.380387,-595.896675;169.628244,-605.236543;169.711739,-604.743048;126.505214,-595.412106;126.630040,-594.927536;169.795233,-604.249552;169.878727,-603.756057;126.754866,-594.442967;126.879692,-593.958398;169.962221,-603.262561;170.045716,-602.769066;127.004518,-593.473828;127.129344,-592.989259;170.129210,-602.275571;170.212704,-601.782075;127.254171,-592.504690;127.378997,-592.020120;170.296199,-601.288580;170.379693,-600.795084;127.503823,-591.535551;127.628649,-591.050982;170.463187,-600.301589;170.546682,-599.808094;127.753475,-590.566412;127.878302,-590.081843;170.630176,-599.314598;170.713670,-598.821103;128.003128,-589.597274;128.127954,-589.112704;170.797165,-598.327607;170.880659,-597.834112;128.252780,-588.628135;128.377606,-588.143566;170.964153,-597.340617;171.047648,-596.847121;128.502433,-587.658996;128.627259,-587.174427;171.131142,-596.353626;171.214636,-595.860130;128.752085,-586.689858;128.876911,-586.205288;171.298131,-595.366635;171.381625,-594.873139;129.001737,-585.720719;129.126564,-585.236150;171.465119,-594.379644;171.548614,-593.886149;129.251390,-584.751580;129.376216,-584.267011;171.632108,-593.392653;171.715602,-592.899158;129.501042,-583.782442;129.625868,-583.297872;171.799097,-592.405662;171.882591,-591.912167;129.750694,-582.813303;129.875521,-582.328734;171.966085,-591.418672;172.049580,-590.925176;130.000347,-581.844165;130.125173,-581.359595;172.133074,-590.431681;172.216568,-589.938185;130.249999,-580.875026;130.374825,-580.390457;172.300063,-589.444690;172.383557,-588.951195;130.499652,-579.905887;130.624478,-579.421318;172.467051,-588.457699;172.550546,-587.964204;130.749304,-578.936749;130.874130,-578.452179;157.378188,-584.176033 |
| | | LAND1.returnPathCoordinates=-1 |
| | | LAND1.returnPathRawCoordinates=-1 |
| | | LAND1.returnPointCoordinates=-1 |
| | | LAND1.updateTime=2025-12-25 16\:37\:39 |
| | | LAND1.updateTime=2025-12-25 19\:02\:14 |
| | | LAND1.userId=-1 |
| | |
| | | #Mower Configuration Properties - Updated |
| | | #Thu Dec 25 16:37:55 CST 2025 |
| | | #Thu Dec 25 19:34:03 CST 2025 |
| | | appVersion=-1 |
| | | boundaryLengthVisible=false |
| | | currentWorkLandNumber=LAND1 |
| | |
| | | handheldMarkerId=1872 |
| | | idleTrailDurationSeconds=60 |
| | | manualBoundaryDrawingMode=false |
| | | mapScale=11.95 |
| | | mapScale=5.20 |
| | | measurementModeEnabled=false |
| | | mowerId=6288 |
| | | serialAutoConnect=true |
| | | serialBaudRate=115200 |
| | | serialPortName=COM15 |
| | | simCardNumber=-1 |
| | | viewCenterX=-148.00 |
| | | viewCenterY=424.51 |
| | | viewCenterX=-141.32 |
| | | viewCenterY=608.58 |
| | |
| | | #\u624B\u52A8\u7ED8\u5236\u8FB9\u754C\u5750\u6807 - \u683C\u5F0F: x1,y1;x2,y2;...;xn,yn (\u5355\u4F4D:\u7C73,\u7CBE\u786E\u5230\u5C0F\u6570\u70B9\u540E2\u4F4D) |
| | | #Tue Dec 23 17:49:02 CST 2025 |
| | | boundaryCoordinates=-99.64,193.56;185.77,182.30;61.84,424.89;237.59,415.88;235.34,539.80;-26.03,544.31 |
| | | #Thu Dec 25 19:00:22 CST 2025 |
| | | boundaryCoordinates=121.86,-611.32;130.67,-577.12;173.17,-587.48;167.47,-621.17 |
| | | email=789 |
| | | language=zh |
| | | lastLoginTime=-1 |
| | | password=123 |
| | | pointCount=6 |
| | | pointCount=4 |
| | | registrationTime=-1 |
| | | status=-1 |
| | | userId=-1 |
| | |
| | | package dikuai; |
| | | |
| | | import javax.swing.*; |
| | | import java.awt.*; |
| | | import java.awt.event.*; |
| | |
| | | import java.util.Objects; |
| | | import java.util.Properties; |
| | | import java.util.Locale; |
| | | |
| | | import lujing.Lunjingguihua; |
| | | import lujing.MowingPathGenerationPage; |
| | | import publicway.Fuzhibutton; |
| | | import publicway.Lookbutton; |
| | |
| | | public boolean savePlannedPath(Dikuai dikuai, String value) { |
| | | return saveFieldAndRefresh(dikuai, "plannedPath", value); |
| | | } |
| | | |
| | | @Override |
| | | public boolean saveMowingSafetyDistance(Dikuai dikuai, String value) { |
| | | return saveFieldAndRefresh(dikuai, "mowingSafetyDistance", value); |
| | | } |
| | | }; |
| | | |
| | | // æ¾ç¤ºè·¯å¾è§åé¡µé¢ |
| | |
| | | } |
| | | } |
| | | String modeValue = sanitizeValueOrNull(dikuai.getMowingPattern()); |
| | | String initialGenerated = attemptMowingPathPreview( |
| | | boundaryValue, |
| | | obstacleValue, |
| | | widthValue, |
| | | modeValue, |
| | | this, |
| | | false |
| | | ); |
| | | // ä¸åé¢å
çæè·¯å¾ï¼ç±è·¯å¾è§å页é¢å¤ç |
| | | String initialGenerated = null; |
| | | showMowingPathDialog(dikuai, baseStationValue, boundaryValue, obstacleValue, widthValue, modeValue, initialGenerated); |
| | | } |
| | | |
| | |
| | | public boolean savePlannedPath(Dikuai dikuai, String value) { |
| | | return saveFieldAndRefresh(dikuai, "plannedPath", value); |
| | | } |
| | | |
| | | @Override |
| | | public boolean saveMowingSafetyDistance(Dikuai dikuai, String value) { |
| | | return saveFieldAndRefresh(dikuai, "mowingSafetyDistance", value); |
| | | } |
| | | }; |
| | | |
| | | // ä½¿ç¨æ°çç¬ç«é¡µé¢ç±» |
| | |
| | | dialog.setVisible(true); |
| | | } |
| | | |
| | | private String attemptMowingPathPreview( |
| | | String boundaryInput, |
| | | String obstacleInput, |
| | | String widthCmInput, |
| | | String modeInput, |
| | | Component parentComponent, |
| | | boolean showMessages) { |
| | | String boundary = sanitizeValueOrNull(boundaryInput); |
| | | if (boundary == null) { |
| | | if (showMessages) { |
| | | JOptionPane.showMessageDialog(parentComponent, "å½åå°åæªè®¾ç½®è¾¹çåæ ï¼æ æ³çæè·¯å¾", "æç¤º", JOptionPane.WARNING_MESSAGE); |
| | | } |
| | | return null; |
| | | } |
| | | String rawWidth = widthCmInput != null ? widthCmInput.trim() : ""; |
| | | String widthStr = sanitizeWidthString(widthCmInput); |
| | | if (widthStr == null) { |
| | | if (showMessages) { |
| | | String message = rawWidth.isEmpty() ? "请å
设置å²è宽度(åç±³)" : "å²èå®½åº¦æ ¼å¼ä¸æ£ç¡®"; |
| | | JOptionPane.showMessageDialog(parentComponent, message, "æç¤º", JOptionPane.WARNING_MESSAGE); |
| | | } |
| | | return null; |
| | | } |
| | | double widthCm; |
| | | try { |
| | | widthCm = Double.parseDouble(widthStr); |
| | | } catch (NumberFormatException ex) { |
| | | if (showMessages) { |
| | | JOptionPane.showMessageDialog(parentComponent, "å²èå®½åº¦æ ¼å¼ä¸æ£ç¡®", "æç¤º", JOptionPane.WARNING_MESSAGE); |
| | | } |
| | | return null; |
| | | } |
| | | if (widthCm <= 0) { |
| | | if (showMessages) { |
| | | JOptionPane.showMessageDialog(parentComponent, "å²è宽度å¿
须大äº0", "æç¤º", JOptionPane.WARNING_MESSAGE); |
| | | } |
| | | return null; |
| | | } |
| | | double widthMeters = widthCm / 100.0d; |
| | | String plannerWidth = BigDecimal.valueOf(widthMeters) |
| | | .setScale(3, RoundingMode.HALF_UP) |
| | | .stripTrailingZeros() |
| | | .toPlainString(); |
| | | String obstacles = sanitizeValueOrNull(obstacleInput); |
| | | if (obstacles != null) { |
| | | obstacles = obstacles.replace("\r\n", " ").replace('\r', ' ').replace('\n', ' '); |
| | | } |
| | | String mode = normalizeExistingMowingPattern(modeInput); |
| | | try { |
| | | String generated = Lunjingguihua.generatePathFromStrings(boundary, obstacles, plannerWidth, mode); |
| | | String trimmed = generated != null ? generated.trim() : ""; |
| | | if (trimmed.isEmpty()) { |
| | | if (showMessages) { |
| | | JOptionPane.showMessageDialog(parentComponent, "æªçæææçå²èè·¯å¾ï¼è¯·æ£æ¥å°åæ°æ®", "æç¤º", JOptionPane.INFORMATION_MESSAGE); |
| | | } |
| | | return null; |
| | | } |
| | | if (showMessages) { |
| | | JOptionPane.showMessageDialog(parentComponent, "å²èè·¯å¾å·²çæ", "æå", JOptionPane.INFORMATION_MESSAGE); |
| | | } |
| | | return trimmed; |
| | | } catch (IllegalArgumentException ex) { |
| | | if (showMessages) { |
| | | JOptionPane.showMessageDialog(parentComponent, "çæå²èè·¯å¾å¤±è´¥: " + ex.getMessage(), "é误", JOptionPane.ERROR_MESSAGE); |
| | | } |
| | | } catch (Exception ex) { |
| | | if (showMessages) { |
| | | JOptionPane.showMessageDialog(parentComponent, "çæå²èè·¯å¾æ¶åçå¼å¸¸: " + ex.getMessage(), "é误", JOptionPane.ERROR_MESSAGE); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | /** |
| | | * å°è¯çæå²èè·¯å¾é¢è§ |
| | | * ç¨äºå¨å¯¹è¯æ¡ä¸å®æ¶é¢è§æçæè·¯å¾ï¼å
å«åæ°æ ¡éªåé误æç¤ºé»è¾ |
| | | * |
| | | * @param boundaryInput å°åè¾¹çåæ å符串 |
| | | * @param obstacleInput éç¢ç©åæ å符串 |
| | | * @param widthCmInput å²è宽度ï¼åç±³ï¼ |
| | | * @param modeInput å²è模å¼ï¼å¹³è¡/èºæï¼ |
| | | * @param parentComponent ç¨äºæ¾ç¤ºæç¤ºæ¡çç¶ç»ä»¶ |
| | | * @param showMessages æ¯å¦æ¾ç¤ºæå/失败çæç¤ºæ¡ |
| | | * @return çæçè·¯å¾å符串ï¼å¦æçæå¤±è´¥ææ ¡éªæªéè¿åè¿å null |
| | | */ |
| | | |
| | | |
| | | private JTextArea createInfoTextArea(String text, boolean editable, int rows) { |
| | | JTextArea area = new JTextArea(text); |
| | |
| | | import java.util.ArrayList; |
| | | import zhuye.Shouye; |
| | | import zhuye.MapRenderer; |
| | | import gecaoji.Device; |
| | | import gecaoji.Gecaoji; |
| | | import gecaoji.lujingdraw; |
| | | import publicway.buttonset; |
| | |
| | | return; |
| | | } |
| | | |
| | | // 2. å°è¯éæ°çæå®æ´è·¯å¾æ®µï¼å
å«å´è¾¹åä½ä¸è·¯å¾ï¼ |
| | | // è¿æ ·å¯ä»¥ç¡®ä¿å¯¼èªé¢è§æ¶ï¼å²èæºå
沿çå
缩边çèµ°ä¸åï¼åèµ°å²èè·¯å¾ |
| | | List<lujing.Lunjingguihua.PathSegment> segments = null; |
| | | String boundaryCoords = dikuai.getBoundaryCoordinates(); |
| | | String mowingWidth = dikuai.getMowingBladeWidth(); // 注æï¼è¿éåºè¯¥ç¨å²è宽度ï¼è䏿¯å²å宽度ï¼é常æ¯ä¸æ ·ç |
| | | // å¦ææ²¡æå²è宽度ï¼å°è¯ä»Deviceè·å |
| | | if (mowingWidth == null || mowingWidth.trim().isEmpty() || "-1".equals(mowingWidth.trim())) { |
| | | Device device = Device.getActiveDevice(); |
| | | if (device != null) { |
| | | mowingWidth = device.getMowingWidth(); |
| | | } |
| | | } |
| | | // å¦æè¿æ¯æ²¡æï¼ä½¿ç¨é»è®¤å¼ |
| | | if (mowingWidth == null || mowingWidth.trim().isEmpty() || "-1".equals(mowingWidth.trim())) { |
| | | mowingWidth = "0.34"; |
| | | } |
| | | |
| | | String safetyDistance = dikuai.getMowingSafetyDistance(); |
| | | String obstaclesCoords = dikuai.getObstacleCoordinates(); |
| | | String mowingPattern = dikuai.getMowingPattern(); |
| | | |
| | | if (boundaryCoords != null && !boundaryCoords.trim().isEmpty() && !"-1".equals(boundaryCoords.trim())) { |
| | | try { |
| | | // è§£æå²èæ¨¡å¼ |
| | | String mode = "parallel"; // é»è®¤å¹³è¡æ¨¡å¼ |
| | | if (mowingPattern != null && !mowingPattern.trim().isEmpty()) { |
| | | String pattern = mowingPattern.trim().toLowerCase(); |
| | | if ("1".equals(pattern) || "spiral".equals(pattern) || "èºæå¼".equals(pattern) || "èºæ".equals(pattern)) { |
| | | mode = "spiral"; |
| | | } else if ("parallel".equals(pattern) || "å¹³è¡çº¿".equals(pattern) || "å¹³è¡".equals(pattern)) { |
| | | mode = "parallel"; |
| | | } |
| | | } |
| | | |
| | | // è°ç¨è·¯å¾è§åçæå®æ´è·¯å¾æ®µ |
| | | segments = lujing.Lunjingguihua.generatePathSegments( |
| | | boundaryCoords, |
| | | obstaclesCoords != null ? obstaclesCoords : "", |
| | | mowingWidth, |
| | | safetyDistance, |
| | | mode |
| | | ); |
| | | } catch (Exception e) { |
| | | // 妿鿰çæå¤±è´¥ï¼segments 为 null |
| | | System.err.println("导èªé¢è§éæ°çæè·¯å¾å¤±è´¥: " + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | // 3. æå»ºæç»å¯¼èªè·¯å¾ç¹å表 |
| | | pathPoints = new ArrayList<>(); |
| | | if (segments != null && !segments.isEmpty()) { |
| | | // 妿æåçæäºè·¯å¾æ®µï¼ä½¿ç¨è·¯å¾æ®µæå»ºç¹å表 |
| | | // è¿æ ·å
å«äºå´è¾¹è·¯å¾åä½ä¸è·¯å¾ï¼ä»¥åå®ä»¬ä¹é´çè¿æ¥ |
| | | lujing.Lunjingguihua.PathSegment firstSeg = segments.get(0); |
| | | pathPoints.add(new Point2D.Double(firstSeg.start.x, firstSeg.start.y)); |
| | | |
| | | for (lujing.Lunjingguihua.PathSegment seg : segments) { |
| | | // æ·»å ç»ç¹ï¼èµ·ç¹å·²ç»å¨ä¸ä¸æ¬¡å¾ªç¯æåå§åæ¶æ·»å äºï¼ |
| | | // 注æï¼è¿éåè®¾è·¯å¾æ®µæ¯è¿ç»çï¼æè
æä»¬åªå
³å¿ç«¯ç¹ |
| | | // å¦ææ®µä¹é´ä¸è¿ç»ï¼æç©ºèµ°ï¼ï¼generatePathSegments åºè¯¥å·²ç»çæäºè¿æ¥æ®µï¼isMowing=falseï¼ |
| | | pathPoints.add(new Point2D.Double(seg.end.x, seg.end.y)); |
| | | } |
| | | } else { |
| | | // 妿çæå¤±è´¥ï¼åéå°ä½¿ç¨åå§è§£æçè·¯å¾ç¹ |
| | | // è¿é常åªå
å«ä½ä¸è·¯å¾ï¼å¯è½æ²¡æå´è¾¹ |
| | | // ç´æ¥ä½¿ç¨è§£æåºæ¥çè·¯å¾ç¹ |
| | | pathPoints = rawPathPoints; |
| | | } |
| | | |
| | | if (pathPoints == null || pathPoints.size() < 2) { |
| | | JOptionPane.showMessageDialog(null, "æ æ³æå»ºææç导èªè·¯å¾", "é误", JOptionPane.ERROR_MESSAGE); |
| | |
| | | package gecaoji; // å
声æ |
| | | |
| | | import java.awt.BasicStroke; // å¼å
¥åºç¡æè¾¹ç±» |
| | | import java.awt.Color; // å¼å
¥é¢è²ç±» |
| | | import java.awt.Graphics2D; // å¼å
¥2Då¾å½¢ä¸ä¸æ |
| | |
| | | import java.awt.geom.Point2D; // å¼å
¥äºç»´ç¹ç±» |
| | | import java.util.ArrayList; // å¼å
¥å¨ææ°ç» |
| | | import java.util.List; // å¼å
¥å表æ¥å£ |
| | | import lujing.Lunjingguihua; // å¼å
¥è·¯å¾è§åç±» |
| | | import org.locationtech.jts.geom.Coordinate; // å¼å
¥åæ ç±» |
| | | import org.locationtech.jts.geom.GeometryFactory; // å¼å
¥å ä½å·¥åç±» |
| | | import org.locationtech.jts.geom.Polygon; // å¼å
¥å¤è¾¹å½¢ç±» |
| | |
| | | // èè² - ç¨äºéä½ä¸ç§»å¨è·¯å¾ |
| | | private static final Color TRAVEL_PATH_COLOR = new Color(0, 0, 255); |
| | | // èçº¿æ ·å¼ - ç¨äºéä½ä¸ç§»å¨è·¯å¾ |
| | | private static final float[] DASH_PATTERN = {10.0f, 5.0f}; |
| | | private static final float[] DASH_PATTERN = {5.0f, 5.0f}; |
| | | private static final Color START_POINT_COLOR = new Color(0, 0, 0, 220); // èµ·ç¹ç®å¤´é¢è² |
| | | private static final Color END_POINT_COLOR = new Color(0, 0, 0, 220); // ç»ç¹ç®å¤´é¢è² |
| | | |
| | |
| | | drawInnerBoundary(g2d, boundaryCoords, safetyDistance, scale); |
| | | } |
| | | |
| | | // 2. å°è¯éæ°çæè·¯å¾æ®µä»¥åºåä½ä¸è·¯å¾åç§»å¨è·¯å¾ |
| | | List<Lunjingguihua.PathSegment> segments = null; |
| | | if (boundaryCoords != null && mowingWidth != null) { |
| | | try { |
| | | // è§£æå²èæ¨¡å¼ |
| | | String mode = "parallel"; // é»è®¤å¹³è¡æ¨¡å¼ |
| | | if (mowingPattern != null && !mowingPattern.trim().isEmpty()) { |
| | | String pattern = mowingPattern.trim().toLowerCase(); |
| | | if ("1".equals(pattern) || "spiral".equals(pattern) || "èºæå¼".equals(pattern) || "èºæ".equals(pattern)) { |
| | | mode = "spiral"; |
| | | } else if ("parallel".equals(pattern) || "å¹³è¡çº¿".equals(pattern) || "å¹³è¡".equals(pattern)) { |
| | | mode = "parallel"; |
| | | } |
| | | } |
| | | segments = Lunjingguihua.generatePathSegments( |
| | | boundaryCoords, |
| | | obstaclesCoords != null ? obstaclesCoords : "", |
| | | mowingWidth, |
| | | safetyDistance, |
| | | mode |
| | | ); |
| | | } catch (Exception e) { |
| | | // 妿鿰çæå¤±è´¥ï¼ä½¿ç¨ç®åç»å¶æ¹å¼ |
| | | segments = null; |
| | | } |
| | | } |
| | | |
| | | // 3. æ ¹æ®æ¯å¦ææ®µä¿¡æ¯éæ©ä¸åçç»å¶æ¹å¼ |
| | | if (segments != null && !segments.isEmpty()) { |
| | | // ææ®µä¿¡æ¯ï¼åå«ç»å¶ä½ä¸è·¯å¾åç§»å¨è·¯å¾ |
| | | drawPathSegments(g2d, segments, scale, arrowScale); |
| | | } else { |
| | | // æ æ®µä¿¡æ¯ï¼ä½¿ç¨ç®åç»å¶æ¹å¼ï¼ææè·¯å¾ä½¿ç¨ä½ä¸è·¯å¾é¢è²ï¼ |
| | | // 2. ç´æ¥ç»å¶è·¯å¾ï¼ä¸åéæ°çæï¼ |
| | | Path2D polyline = new Path2D.Double(); // å建æçº¿ |
| | | boolean move = true; // 馿®µæ è®° |
| | | for (Point2D.Double point : path) { // éåç¹é |
| | |
| | | |
| | | drawArrowMarker(g2d, start, second, START_POINT_COLOR, scale, arrowScale); // ç»å¶èµ·ç¹ç®å¤´ |
| | | drawArrowMarker(g2d, prev, end, END_POINT_COLOR, scale, arrowScale); // ç»å¶ç»ç¹ç®å¤´ |
| | | } |
| | | |
| | | g2d.setStroke(previous); // æ¢å¤åæè¾¹ |
| | | } // æ¹æ³ç»æ |
| | |
| | | */ // ææ¡£æ³¨éç»æ |
| | | private static void drawInnerBoundary(Graphics2D g2d, String boundaryCoords, String safetyDistanceStr, double scale) { |
| | | try { |
| | | List<Coordinate> boundary = Lunjingguihua.parseCoordinates(boundaryCoords); |
| | | List<Coordinate> boundary = parseCoordinates(boundaryCoords); |
| | | if (boundary.size() < 4) { |
| | | return; // è¾¹çç¹ä¸è¶³ |
| | | } |
| | |
| | | } |
| | | } // æ¹æ³ç»æ |
| | | |
| | | /** // ææ¡£æ³¨éå¼å§ |
| | | * ç»å¶è·¯å¾æ®µï¼åºåä½ä¸è·¯å¾åç§»å¨è·¯å¾ï¼ |
| | | */ // ææ¡£æ³¨éç»æ |
| | | private static void drawPathSegments(Graphics2D g2d, List<Lunjingguihua.PathSegment> segments, double scale, double arrowScale) { |
| | | if (segments == null || segments.isEmpty()) { |
| | | return; |
| | | } |
| | | |
| | | float strokeWidth = (float) (2.5 / Math.max(0.5, scale)); |
| | | Stroke previous = g2d.getStroke(); |
| | | |
| | | // åå«ç»å¶ä½ä¸è·¯å¾åç§»å¨è·¯å¾ |
| | | Path2D.Double mowingPath = new Path2D.Double(); |
| | | Path2D.Double travelPath = new Path2D.Double(); |
| | | boolean mowingStarted = false; |
| | | boolean travelStarted = false; |
| | | |
| | | Coordinate lastMowingEnd = null; |
| | | Coordinate lastTravelEnd = null; |
| | | |
| | | for (Lunjingguihua.PathSegment seg : segments) { |
| | | if (seg == null || seg.start == null || seg.end == null) { |
| | | continue; |
| | | } |
| | | |
| | | if (seg.isMowing) { |
| | | // ä½ä¸è·¯å¾ - æé¦çº¢70%éæåº¦ |
| | | if (!mowingStarted || lastMowingEnd == null || !equals2D(lastMowingEnd, seg.start)) { |
| | | mowingPath.moveTo(seg.start.x, seg.start.y); |
| | | mowingStarted = true; |
| | | } |
| | | mowingPath.lineTo(seg.end.x, seg.end.y); |
| | | lastMowingEnd = seg.end; |
| | | } else { |
| | | // ç§»å¨è·¯å¾ - èè²è线 |
| | | if (!travelStarted || lastTravelEnd == null || !equals2D(lastTravelEnd, seg.start)) { |
| | | travelPath.moveTo(seg.start.x, seg.start.y); |
| | | travelStarted = true; |
| | | } |
| | | travelPath.lineTo(seg.end.x, seg.end.y); |
| | | lastTravelEnd = seg.end; |
| | | } |
| | | } |
| | | |
| | | // ç»å¶ä½ä¸è·¯å¾ |
| | | if (mowingStarted) { |
| | | g2d.setColor(MOWING_PATH_COLOR); // æé¦çº¢70%éæåº¦ |
| | | g2d.setStroke(new BasicStroke(strokeWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); |
| | | g2d.draw(mowingPath); |
| | | } |
| | | |
| | | // ç»å¶ç§»å¨è·¯å¾ï¼èçº¿ï¼ |
| | | if (travelStarted) { |
| | | g2d.setColor(TRAVEL_PATH_COLOR); // èè² |
| | | g2d.setStroke(new BasicStroke(strokeWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0, DASH_PATTERN, 0)); |
| | | g2d.draw(travelPath); |
| | | } |
| | | |
| | | // ç»å¶èµ·ç¹åç»ç¹ç®å¤´ |
| | | if (!segments.isEmpty()) { |
| | | Lunjingguihua.PathSegment firstSeg = segments.get(0); |
| | | if (firstSeg != null && firstSeg.start != null && segments.size() > 1) { |
| | | Lunjingguihua.PathSegment secondSeg = segments.get(1); |
| | | if (secondSeg != null && secondSeg.start != null) { |
| | | Point2D.Double start = new Point2D.Double(firstSeg.start.x, firstSeg.start.y); |
| | | Point2D.Double second = new Point2D.Double(secondSeg.start.x, secondSeg.start.y); |
| | | drawArrowMarker(g2d, start, second, START_POINT_COLOR, scale, arrowScale); |
| | | } |
| | | } |
| | | |
| | | Lunjingguihua.PathSegment lastSeg = segments.get(segments.size() - 1); |
| | | if (lastSeg != null && lastSeg.end != null && segments.size() > 1) { |
| | | Lunjingguihua.PathSegment prevSeg = segments.get(segments.size() - 2); |
| | | if (prevSeg != null && prevSeg.end != null) { |
| | | Point2D.Double prev = new Point2D.Double(prevSeg.end.x, prevSeg.end.y); |
| | | Point2D.Double end = new Point2D.Double(lastSeg.end.x, lastSeg.end.y); |
| | | drawArrowMarker(g2d, prev, end, END_POINT_COLOR, scale, arrowScale); |
| | | } |
| | | } |
| | | } |
| | | |
| | | g2d.setStroke(previous); |
| | | } // æ¹æ³ç»æ |
| | | |
| | | /** // ææ¡£æ³¨éå¼å§ |
| | | * æ¯è¾ä¸¤ä¸ªåæ æ¯å¦ç¸åï¼å®¹å·®ï¼ |
| | |
| | | g2d.setColor(color); // 设置é¢è² |
| | | g2d.fill(arrow); // å¡«å
ç®å¤´ |
| | | } // æ¹æ³ç»æ |
| | | |
| | | /** |
| | | * è§£æåæ å符串 |
| | | */ |
| | | private static List<Coordinate> parseCoordinates(String s) { |
| | | List<Coordinate> list = new ArrayList<>(); |
| | | if (s == null || s.trim().isEmpty()) return list; |
| | | // å¢å¼ºæ£åï¼å¤çå¯è½åå¨çå¤ç§åé符 |
| | | String[] pts = s.split("[;\\s]+"); |
| | | for (String p : pts) { |
| | | String trimmed = p.trim().replace("(", "").replace(")", ""); |
| | | if (trimmed.isEmpty()) continue; |
| | | String[] xy = trimmed.split("[,ï¼\\s]+"); |
| | | if (xy.length >= 2) { |
| | | try { |
| | | double x = Double.parseDouble(xy[0].trim()); |
| | | double y = Double.parseDouble(xy[1].trim()); |
| | | // è¿æ»¤æ æåæ |
| | | if (!Double.isNaN(x) && !Double.isNaN(y) && !Double.isInfinite(x) && !Double.isInfinite(y)) { |
| | | list.add(new Coordinate(x, y)); |
| | | } |
| | | } catch (NumberFormatException ex) { |
| | | // 忽ç¥è§£æé误çç¹ |
| | | } |
| | | } |
| | | } |
| | | // ç¡®ä¿å¤è¾¹å½¢éå |
| | | if (list.size() > 2 && !list.get(0).equals2D(list.get(list.size() - 1))) { |
| | | list.add(new Coordinate(list.get(0))); |
| | | } |
| | | return list; |
| | | } |
| | | } // ç±»ç»æ |
| | |
| | | package lujing; |
| | | |
| | | import javax.swing.*; |
| | | import javax.swing.SwingUtilities; |
| | | import java.awt.*; |
| | | import java.awt.event.ActionEvent; |
| | | import java.awt.event.ActionListener; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | import dikuai.Dikuai; |
| | | import lujing.Lunjingguihua; |
| | | import lujing.ObstaclePathPlanner; |
| | | import lujing.Qufenxingzhuang; |
| | | import lujing.AoxinglujingNoObstacle; |
| | | import lujing.YixinglujingNoObstacle; |
| | | import publicway.Fuzhibutton; |
| | | import lujing.AoxinglujingHaveObstacel; |
| | | import lujing.YixinglujingHaveObstacel; |
| | | import org.locationtech.jts.geom.Coordinate; |
| | | import gecaoji.Device; |
| | | import java.util.Locale; |
| | | |
| | |
| | | boolean saveObstacleCoordinates(Dikuai dikuai, String baseStationValue, String obstacleValue); |
| | | boolean saveMowingWidth(Dikuai dikuai, String value); |
| | | boolean savePlannedPath(Dikuai dikuai, String value); |
| | | boolean saveMowingSafetyDistance(Dikuai dikuai, String value); |
| | | } |
| | | |
| | | private final Dikuai dikuai; |
| | |
| | | * é¢è§è·¯å¾ |
| | | */ |
| | | private void previewPath() { |
| | | // å
ä¿åå½åè·¯å¾å°å°åï¼ä¸´æ¶ä¿åï¼ç¨äºé¢è§ï¼ |
| | | String pathNormalized = normalizeCoordinateInput(pathArea.getText()); |
| | | // ç´æ¥ä»ææ¬åè·åè·¯å¾æ°æ® |
| | | String rawPath = pathArea.getText(); |
| | | String pathNormalized = normalizeCoordinateInput(rawPath); |
| | | |
| | | if (!"-1".equals(pathNormalized)) { |
| | | // è§èåè·¯å¾æ°æ®ï¼æ¯ææ¢è¡ãç©ºæ ¼çåé符 |
| | | pathNormalized = pathNormalized |
| | | .replace("\r\n", ";") |
| | | .replace('\r', ';') |
| | | .replace('\n', ';') |
| | | .replaceAll(";+", ";") |
| | | .replaceAll("\\s*;\\s*", ";") |
| | | .trim(); |
| | | .replaceAll("\\s+", ";") // å°ææç©ºç½åç¬¦æ¿æ¢ä¸ºåå· |
| | | .replaceAll(";+", ";"); // åå¹¶è¿ç»åå· |
| | | |
| | | // å»é¤é¦å°¾åå· |
| | | if (pathNormalized.startsWith(";")) pathNormalized = pathNormalized.substring(1); |
| | | if (pathNormalized.endsWith(";")) pathNormalized = pathNormalized.substring(0, pathNormalized.length() - 1); |
| | | |
| | | if (pathNormalized.isEmpty()) { |
| | | pathNormalized = "-1"; |
| | | } |
| | | } |
| | | |
| | | if ("-1".equals(pathNormalized)) { |
| | | JOptionPane.showMessageDialog(this, "请å
çæå²èè·¯å¾", "æç¤º", JOptionPane.INFORMATION_MESSAGE); |
| | | JOptionPane.showMessageDialog(this, "请å
çæå²èè·¯å¾æå¨ææ¬æ¡ä¸è¾å
¥ææåæ ", "æç¤º", JOptionPane.INFORMATION_MESSAGE); |
| | | return; |
| | | } |
| | | |
| | | // 临æ¶ä¿åè·¯å¾å°å°å对象ï¼ä¸æä¹
åï¼ |
| | | if (saveCallback != null) { |
| | | saveCallback.savePlannedPath(dikuai, pathNormalized); |
| | | } |
| | | // 注æï¼é¢è§æ¶ä¸èªå¨ä¿åè·¯å¾å°å°åï¼ä»
ä½¿ç¨ææ¬åä¸çæ°æ®è¿è¡é¢è§ |
| | | // åªæç¹å»"ä¿åè·¯å¾"æé®æ¶ææä¹
åæ°æ® |
| | | |
| | | // ä¿åå½å页é¢ç¶æï¼ç¨äºè¿åæ¶æ¢å¤ |
| | | String currentBaseStation = baseStationField.getText(); |
| | |
| | | String boundaryInput = normalizeCoordinateInput(boundaryArea.getText()); |
| | | final String boundary; |
| | | if (!"-1".equals(boundaryInput)) { |
| | | String processed = boundaryInput.replace("\r\n", ";") |
| | | String processed = boundaryInput |
| | | .replace("\r\n", ";") |
| | | .replace('\r', ';') |
| | | .replace('\n', ';') |
| | | .replaceAll(";+", ";") |
| | | .replaceAll("\\s*;\\s*", ";") |
| | | .trim(); |
| | | .replaceAll("\\s+", ";") |
| | | .replaceAll(";+", ";"); |
| | | |
| | | if (processed.startsWith(";")) processed = processed.substring(1); |
| | | if (processed.endsWith(";")) processed = processed.substring(0, processed.length() - 1); |
| | | |
| | | if (processed.isEmpty()) { |
| | | boundary = dikuai.getBoundaryCoordinates(); |
| | | } else { |
| | |
| | | dikuai.setMowingWidth(widthNormalized); |
| | | dikuai.setPlannedPath(pathNormalized); |
| | | dikuai.setObstacleCoordinates(obstacleNormalized); |
| | | |
| | | // è·åå¹¶æ´æ°å®å
¨è·ç¦» |
| | | String safetyDistance = getSafetyDistanceString(); |
| | | if (safetyDistance != null) { |
| | | dikuai.setMowingSafetyDistance(safetyDistance); |
| | | } |
| | | } |
| | | |
| | | // è°ç¨åè°ä¿åæ°æ® |
| | |
| | | JOptionPane.showMessageDialog(this, "æ æ³ä¿åå²èè·¯å¾", "é误", JOptionPane.ERROR_MESSAGE); |
| | | return; |
| | | } |
| | | |
| | | // ä¿åå®å
¨è·ç¦» |
| | | String safetyDistance = getSafetyDistanceString(); |
| | | if (safetyDistance != null) { |
| | | if (!saveCallback.saveMowingSafetyDistance(dikuai, safetyDistance)) { |
| | | JOptionPane.showMessageDialog(this, "æ æ³ä¿åå²èå®å
¨è·ç¦»", "é误", JOptionPane.ERROR_MESSAGE); |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | |
| | | JOptionPane.showMessageDialog(this, "å²èè·¯å¾å·²ä¿å", "æå", JOptionPane.INFORMATION_MESSAGE); |
| | |
| | | |
| | | String obstacles = sanitizeValueOrNull(obstacleInput); |
| | | if (obstacles != null) { |
| | | // æç
§ç¨æ·è¦æ±ï¼å¤ä¸ªéç¢ç©ä¹é´ç¨ $ 符å·åé |
| | | // 妿è¾å
¥ä¸å
å« $ï¼åä¿ç $ï¼å¦åå°æ¢è¡ç¬¦æ¿æ¢ä¸º $ |
| | | if (obstacles.contains("$")) { |
| | | // å·²ç»æ¯ $ åéçæ ¼å¼ï¼åªéæ¸
çæ¢è¡ç¬¦ |
| | | obstacles = obstacles.replace("\r\n", " ").replace('\r', ' ').replace('\n', ' '); |
| | | } else { |
| | | // å°è¯å°æ¢è¡ç¬¦è½¬æ¢ä¸º $ï¼æè
妿æ¯ä¸è¡åä¿æåæ · |
| | | // è¿éåè®¾ç¨æ·å¯è½ç¨æ¢è¡åéå¤ä¸ªéç¢ç© |
| | | // 使 ¹æ®éæ±æè¿°ï¼ä¼¼ä¹è¾å
¥æ¬èº«å°±åºè¯¥æ¯ $ åéçï¼æè
æä»¬éè¦å¤çæ $ åé |
| | | // 为äºå
¼å®¹æ§ï¼å¦æç¨æ·è¾å
¥çæ¯æ¢è¡åéçå¤ä¸ªéç¢ç©ï¼æä»¬å°å
¶è½¬æ¢ä¸º $ åé |
| | | // ä½é常éç¢ç©åæ æ¯ä¸ä¸²åæ ç¹ï¼å¦æç¨æ·æ²¡ææ¾å¼ç¨ $ åéï¼æä»¬å¾é¾åºåæ¯åä¸ä¸ªéç¢ç©çç¹è¿æ¯å¤ä¸ªéç¢ç© |
| | | // å æ¤ï¼è¿é主è¦å¤çæ¸
çå·¥ä½ï¼å
·ä½çè§£æé»è¾å¨åå®ç°ç±»ä¸å¤ç |
| | | obstacles = obstacles.replace("\r\n", " ").replace('\r', ' ').replace('\n', ' '); |
| | | } |
| | | } |
| | | |
| | | // è·åå®å
¨è·ç¦» |
| | |
| | | int grassType = shapeJudger.judgeGrassType(boundary); |
| | | // grassType: 0=æ æ³å¤æ, 1=å¸å½¢, 2=å¼å½¢ |
| | | |
| | | // è§£æéç¢ç©å表 |
| | | List<List<Coordinate>> obstacleList = Lunjingguihua.parseObstacles(obstacles); |
| | | if (obstacleList == null) { |
| | | obstacleList = new ArrayList<>(); |
| | | } |
| | | |
| | | // 夿æ¯å¦æææçéç¢ç©ï¼åªæå½è§£ææåä¸å表ä¸ä¸ºç©ºæ¶ï¼æè®¤ä¸ºæéç¢ç© |
| | | boolean hasValidObstacles = !obstacleList.isEmpty(); |
| | | |
| | | String generated = null; |
| | | |
| | | // 2. æ ¹æ®å°åç±»å忝妿éç¢ç©ï¼è°ç¨ä¸åçè·¯å¾çæç±» |
| | | if (!hasValidObstacles) { |
| | | if (!hasObstacleInput) { |
| | | // æ éç¢ç©çæ
åµ |
| | | if (grassType == 1) { |
| | | // å¸å½¢å°åï¼æ éç¢ç© -> è°ç¨ AoxinglujingNoObstacle |
| | |
| | | generated = formatAoxingPathSegments(segments); |
| | | } else if (grassType == 2) { |
| | | // å¼å½¢å°åï¼æ éç¢ç© -> è°ç¨ YixinglujingNoObstacle |
| | | // 注æï¼å¦æè¯¥ç±»è¿æ²¡æå®ç°ï¼è¿é伿åºå¼å¸¸æè¿ånull |
| | | try { |
| | | // è°ç¨ YixinglujingNoObstacle.planPath è·åè·¯å¾æ®µå表 |
| | | List<YixinglujingNoObstacle.PathSegment> segments = |
| | | YixinglujingNoObstacle.planPath(boundary, plannerWidth, safetyMarginStr); |
| | | // æ ¼å¼åè·¯å¾æ®µå表为å符串 |
| | | generated = formatYixingPathSegments(segments); |
| | | } catch (Exception e) { |
| | | // å¦æç±»è¿æ²¡æå®ç°ï¼ä½¿ç¨åæ¥çæ¹æ³ä½ä¸ºåå¤ |
| | | if (showMessages) { |
| | | System.err.println("YixinglujingNoObstacle å°æªå®ç°ï¼ä½¿ç¨é»è®¤æ¹æ³: " + e.getMessage()); |
| | | } |
| | | generated = Lunjingguihua.generatePathFromStrings( |
| | | boundary, obstacles != null ? obstacles : "", plannerWidth, safetyMarginStr, mode); |
| | | } |
| | | } else { |
| | | // æ æ³å¤æå°åç±»åï¼ä½¿ç¨åæ¥çæ¹æ³ä½ä¸ºåå¤ |
| | | // æ æ³å¤æå°åç±»åï¼é»è®¤æå¸å½¢å¤çææç¤º |
| | | if (showMessages) { |
| | | JOptionPane.showMessageDialog(parentComponent, "æ æ³å¤æå°åç±»åï¼ä½¿ç¨é»è®¤è·¯å¾çææ¹æ³", |
| | | JOptionPane.showMessageDialog(parentComponent, "æ æ³å¤æå°åç±»åï¼å°è¯æå¸å½¢å°åå¤ç", |
| | | "æç¤º", JOptionPane.WARNING_MESSAGE); |
| | | } |
| | | generated = Lunjingguihua.generatePathFromStrings( |
| | | boundary, obstacles != null ? obstacles : "", plannerWidth, safetyMarginStr, mode); |
| | | List<AoxinglujingNoObstacle.PathSegment> segments = |
| | | AoxinglujingNoObstacle.planPath(boundary, plannerWidth, safetyMarginStr); |
| | | generated = formatAoxingPathSegments(segments); |
| | | } |
| | | } else { |
| | | // æéç¢ç©çæ
åµ |
| | | if (grassType == 1) { |
| | | // å¸å½¢å°åï¼æéç¢ç© -> è°ç¨ AoxinglujingHaveObstacel |
| | | try { |
| | | // å设 AoxinglujingHaveObstacel æç±»ä¼¼çæ¹æ³ç¾å |
| | | List<AoxinglujingHaveObstacel.PathSegment> segments = AoxinglujingHaveObstacel.planPath(boundary, obstacles, plannerWidth, safetyMarginStr); |
| | | // ä¼ å
¥åæ°ï¼boundary(A), obstacles(B), plannerWidth(C), safetyMarginStr(D) |
| | | List<AoxinglujingHaveObstacel.PathSegment> segments = |
| | | AoxinglujingHaveObstacel.planPath(boundary, obstacles, plannerWidth, safetyMarginStr); |
| | | generated = formatAoxingHaveObstaclePathSegments(segments); |
| | | } catch (Exception e) { |
| | | // å¦æç±»è¿æ²¡æå®ç°ï¼ä½¿ç¨åæ¥çæ¹æ³ä½ä¸ºåå¤ |
| | | if (showMessages) { |
| | | System.err.println("AoxinglujingHaveObstacel å°æªå®ç°ï¼ä½¿ç¨é»è®¤æ¹æ³: " + e.getMessage()); |
| | | } |
| | | List<Coordinate> polygon = Lunjingguihua.parseCoordinates(boundary); |
| | | if (polygon.size() < 4) { |
| | | if (showMessages) { |
| | | JOptionPane.showMessageDialog(parentComponent, "å¤è¾¹å½¢åæ æ°éä¸è¶³ï¼è³å°éè¦ä¸ä¸ªç¹", |
| | | "é误", JOptionPane.ERROR_MESSAGE); |
| | | } |
| | | return null; |
| | | } |
| | | double safetyDistance = Double.parseDouble(safetyMarginStr); |
| | | ObstaclePathPlanner pathPlanner = new ObstaclePathPlanner( |
| | | polygon, widthMeters, mode, obstacleList, safetyDistance); |
| | | List<Lunjingguihua.PathSegment> segments = pathPlanner.generate(); |
| | | generated = Lunjingguihua.formatPathSegments(segments); |
| | | } |
| | | } else if (grassType == 2) { |
| | | // å¼å½¢å°åï¼æéç¢ç© -> è°ç¨ YixinglujingHaveObstacel |
| | | try { |
| | | // å设 YixinglujingHaveObstacel æç±»ä¼¼çæ¹æ³ç¾å |
| | | // ä¼ å
¥åæ°ï¼boundary(A), obstacles(B), plannerWidth(C), safetyMarginStr(D) |
| | | // 注æï¼YixinglujingHaveObstacel.planPath è¿å String |
| | | generated = YixinglujingHaveObstacel.planPath(boundary, obstacles, plannerWidth, safetyMarginStr); |
| | | } catch (Exception e) { |
| | | // å¦æç±»è¿æ²¡æå®ç°ï¼ä½¿ç¨åæ¥çæ¹æ³ä½ä¸ºåå¤ |
| | | if (showMessages) { |
| | | System.err.println("YixinglujingHaveObstacel å°æªå®ç°ï¼ä½¿ç¨é»è®¤æ¹æ³: " + e.getMessage()); |
| | | } |
| | | List<Coordinate> polygon = Lunjingguihua.parseCoordinates(boundary); |
| | | if (polygon.size() < 4) { |
| | | if (showMessages) { |
| | | JOptionPane.showMessageDialog(parentComponent, "å¤è¾¹å½¢åæ æ°éä¸è¶³ï¼è³å°éè¦ä¸ä¸ªç¹", |
| | | "é误", JOptionPane.ERROR_MESSAGE); |
| | | } |
| | | return null; |
| | | } |
| | | double safetyDistance = Double.parseDouble(safetyMarginStr); |
| | | ObstaclePathPlanner pathPlanner = new ObstaclePathPlanner( |
| | | polygon, widthMeters, mode, obstacleList, safetyDistance); |
| | | List<Lunjingguihua.PathSegment> segments = pathPlanner.generate(); |
| | | generated = Lunjingguihua.formatPathSegments(segments); |
| | | } |
| | | } else { |
| | | // æ æ³å¤æå°åç±»åï¼ä½¿ç¨åæ¥çæ¹æ³ä½ä¸ºåå¤ |
| | | // æ æ³å¤æå°åç±»åï¼é»è®¤æå¸å½¢å¤çææç¤º |
| | | if (showMessages) { |
| | | JOptionPane.showMessageDialog(parentComponent, "æ æ³å¤æå°åç±»åï¼ä½¿ç¨é»è®¤è·¯å¾çææ¹æ³", |
| | | JOptionPane.showMessageDialog(parentComponent, "æ æ³å¤æå°åç±»åï¼å°è¯æå¸å½¢å°åå¤ç", |
| | | "æç¤º", JOptionPane.WARNING_MESSAGE); |
| | | } |
| | | List<Coordinate> polygon = Lunjingguihua.parseCoordinates(boundary); |
| | | if (polygon.size() < 4) { |
| | | if (showMessages) { |
| | | JOptionPane.showMessageDialog(parentComponent, "å¤è¾¹å½¢åæ æ°éä¸è¶³ï¼è³å°éè¦ä¸ä¸ªç¹", |
| | | "é误", JOptionPane.ERROR_MESSAGE); |
| | | } |
| | | return null; |
| | | } |
| | | double safetyDistance = Double.parseDouble(safetyMarginStr); |
| | | ObstaclePathPlanner pathPlanner = new ObstaclePathPlanner( |
| | | polygon, widthMeters, mode, obstacleList, safetyDistance); |
| | | List<Lunjingguihua.PathSegment> segments = pathPlanner.generate(); |
| | | generated = Lunjingguihua.formatPathSegments(segments); |
| | | List<AoxinglujingHaveObstacel.PathSegment> segments = |
| | | AoxinglujingHaveObstacel.planPath(boundary, obstacles, plannerWidth, safetyMarginStr); |
| | | generated = formatAoxingHaveObstaclePathSegments(segments); |
| | | } |
| | | } |
| | | |
| | |
| | | import dikuai.Gecaokuanjisuan; |
| | | import dikuai.Gecaoanquanjuli; |
| | | import bianjie.Bianjieyouhuatoxy; |
| | | import lujing.Lunjingguihua; |
| | | |
| | | import lujing.Qufenxingzhuang; |
| | | import lujing.AoxinglujingNoObstacle; |
| | | import lujing.YixinglujingNoObstacle; |
| | |
| | | YixinglujingNoObstacle.planPath(boundaryCoords, widthMetersStr, safetyDistanceMetersStr); |
| | | plannedPath = formatYixingPathSegments(segments); |
| | | } else { |
| | | // æ æ³å¤æå°åç±»åï¼ä½¿ç¨é»è®¤æ¹æ³ä½ä¸ºåå¤ |
| | | JOptionPane.showMessageDialog(this, "æ æ³å¤æå°åç±»åï¼ä½¿ç¨é»è®¤è·¯å¾çææ¹æ³", |
| | | // æ æ³å¤æå°åç±»å |
| | | JOptionPane.showMessageDialog(this, "æ æ³å¤æå°åç±»åï¼æ æ³çæè·¯å¾", |
| | | "æç¤º", JOptionPane.WARNING_MESSAGE); |
| | | String plannerMode = resolvePlannerMode(patternDisplay); |
| | | plannedPath = Lunjingguihua.generatePathFromStrings( |
| | | boundaryCoords, |
| | | obstacleCoords != null ? obstacleCoords : "", |
| | | widthMetersStr, |
| | | safetyDistanceMetersStr, |
| | | plannerMode |
| | | ); |
| | | plannedPath = ""; |
| | | } |
| | | |
| | | if (!isMeaningfulValue(plannedPath)) { |