张世豪
7 小时以前 5b685e9066ccfbc432c29739b5524f1d42a20891
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
package dikuai;
 
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
 
import bianjie.bianjieguihua2;
import publicway.Fuzhibutton;
import zhuye.Coordinate;
import zhuye.Shouye;
import java.text.SimpleDateFormat;
import java.util.Date;
 
/**
 * 地块边界管理页面
 * 显示:原始边界坐标(经纬度、高程)、原始边界XY(相对于基准站)、以及可编辑的优化后边界坐标
 */
public class Dikuanbianjipage extends JDialog {
    private static final long serialVersionUID = 1L;
    private static final int SCREEN_WIDTH = 400;
    private static final int SCREEN_HEIGHT = 800;
    private static final Color PRIMARY_COLOR = new Color(46, 139, 87);
    private static final Color PRIMARY_DARK = new Color(30, 107, 69);
    private static final Color TEXT_COLOR = new Color(51, 51, 51);
    private static final Color WHITE = Color.WHITE;
    private static final Color BORDER_COLOR = new Color(200, 200, 200);
    private static final Color BACKGROUND_COLOR = new Color(250, 250, 250);
 
    private String result = null;
    private Dikuai dikuai;
 
    public Dikuanbianjipage(Window owner, String title, String initialValue, Dikuai dikuai) {
        super(owner, title, Dialog.ModalityType.APPLICATION_MODAL);
        this.dikuai = dikuai;
        initializeUI(title, initialValue, dikuai);
    }
 
    public String getResult() {
        return result;
    }
 
    private void initializeUI(String title, String initialValue, Dikuai dikuai) {
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout());
        getContentPane().setBackground(BACKGROUND_COLOR);
 
        JPanel contentPanel = new JPanel();
        contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
        contentPanel.setBackground(BACKGROUND_COLOR);
        contentPanel.setBorder(BorderFactory.createEmptyBorder(12, 16, 12, 16));
 
        String landName = dikuai != null ? (dikuai.getLandName() != null ? dikuai.getLandName() : "未知地块") : "未知地块";
        String landNumber = dikuai != null ? (dikuai.getLandNumber() != null ? dikuai.getLandNumber() : "未知编号") : "未知编号";
        JLabel headerLabel = new JLabel(landName + " / " + landNumber);
        headerLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
        headerLabel.setForeground(TEXT_COLOR);
        headerLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
        contentPanel.add(headerLabel);
        contentPanel.add(Box.createVerticalStrut(12));
 
        // 原始边界坐标(经纬度, 高程)
        String rawCoords = dikuai != null ? prepareCoordinateForEditor(dikuai.getBoundaryOriginalCoordinates()) : "";
        int rawCount = 0;
        if (rawCoords != null && !rawCoords.isEmpty() && !"-1".equals(rawCoords)) {
            rawCount = rawCoords.split(";").length;
        }
        JTextArea rawTextArea = createInfoTextArea(rawCoords, false, 6);
        contentPanel.add(createTextAreaSection("原始边界坐标 (经度, 纬度, 高程) (" + rawCount + "点)", rawTextArea));
 
        // 原始边界XY坐标(相对于基准站)
        String rawXY = dikuai != null ? prepareCoordinateForEditor(dikuai.getBoundaryOriginalXY()) : "";
        int xyCount = 0;
        if (rawXY != null && !rawXY.isEmpty() && !"-1".equals(rawXY)) {
            xyCount = rawXY.split(";").length;
        }
        JTextArea rawXYArea = createInfoTextArea(rawXY, false, 6);
        contentPanel.add(createTextAreaSection("原始边界XY坐标(相对于基准站) (" + xyCount + "点)", rawXYArea));
 
        // 优化后边界坐标(可编辑)
        String optCoords = prepareCoordinateForEditor(initialValue);
        int optCount = 0;
        if (optCoords != null && !optCoords.isEmpty() && !"-1".equals(optCoords)) {
            optCount = optCoords.split(";").length;
        }
        JTextArea optTextArea = createInfoTextArea(optCoords, true, 6);
        contentPanel.add(createTextAreaSection("优化后地块边界坐标 (" + optCount + "点)", optTextArea));
 
        JScrollPane dialogScrollPane = new JScrollPane(contentPanel);
        dialogScrollPane.setBorder(BorderFactory.createEmptyBorder());
        dialogScrollPane.getVerticalScrollBar().setUnitIncrement(16);
        add(dialogScrollPane, BorderLayout.CENTER);
 
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 12, 12));
        buttonPanel.setBackground(BACKGROUND_COLOR);
 
        JButton optimizeBtn = createPrimaryFooterButton("优化边界坐标");
        JButton saveBtn = createPrimaryFooterButton("保存");
        JButton previewBtn = createPrimaryFooterButton("预览");
        JButton closeBtn = createPrimaryFooterButton("关闭");
 
        optimizeBtn.addActionListener(e -> {
            if (dikuai == null) {
                JOptionPane.showMessageDialog(this, "未找到地块信息,无法优化", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
            
            // 从原始边界XY坐标文本域获取输入
            String inputXY = rawXYArea.getText();
            if (inputXY == null || inputXY.trim().isEmpty() || "-1".equals(inputXY.trim())) {
                JOptionPane.showMessageDialog(this, "原始边界XY坐标为空,无法优化", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
 
            try {
                // 调用优化算法(直接使用XY坐标字符串)
                String optimized = bianjieguihua2.optimizeBoundaryXYString(inputXY.trim());
                optTextArea.setText(optimized);
                JOptionPane.showMessageDialog(this, "边界优化完成", "提示", JOptionPane.INFORMATION_MESSAGE);
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(this, "优化失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                ex.printStackTrace();
            }
        });
 
        previewBtn.addActionListener(e -> {
            if (dikuai == null) {
                return;
            }
            // 关闭当前对话框
            dispose();
            
            // 获取当前优化后的边界
            String currentOptimized = optTextArea.getText();
            
            // 保存地块编号,用于返回回调
            final String targetLandNumber = dikuai.getLandNumber();
            
            // 调用首页显示预览
            SwingUtilities.invokeLater(() -> {
                Shouye.showBoundaryPreview(dikuai, currentOptimized, () -> {
                    // 返回回调:重新打开此页面,从地块对象重新读取最新的边界坐标
                    // 从 dikuaiMap 重新获取地块对象(确保获取到最新的值)
                    Dikuai updatedDikuai = Dikuai.getDikuai(targetLandNumber);
                    if (updatedDikuai != null) {
                        String latestBoundary = updatedDikuai.getBoundaryCoordinates();
                        new Dikuanbianjipage(getOwner(), getTitle(), latestBoundary, updatedDikuai).setVisible(true);
                    } else {
                        // 如果获取失败,使用当前值
                        new Dikuanbianjipage(getOwner(), getTitle(), currentOptimized, dikuai).setVisible(true);
                    }
                });
            });
        });
 
        saveBtn.addActionListener(e -> {
            if (dikuai == null) {
                JOptionPane.showMessageDialog(this, "未找到地块信息,无法保存", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
            String currentText = optTextArea.getText();
            if (currentText == null || currentText.trim().isEmpty() || "-1".equals(currentText.trim())) {
                JOptionPane.showMessageDialog(this, "优化后地块边界为空,无法保存", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }
            String trimmed = currentText.trim();
            // 保存到地块对象
            if (!Dikuai.updateField(dikuai.getLandNumber(), "boundaryCoordinates", trimmed)) {
                JOptionPane.showMessageDialog(this, "无法更新地块边界坐标", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
            Dikuai.updateField(dikuai.getLandNumber(), "updateTime", getCurrentTime());
            Dikuai.saveToProperties();
            this.result = trimmed;
            JOptionPane.showMessageDialog(this, "地块边界坐标已更新", "成功", JOptionPane.INFORMATION_MESSAGE);
            // 不退出页面,只更新显示
            // dispose(); // 移除退出逻辑
        });
 
        closeBtn.addActionListener(e -> dispose());
 
        // 按钮顺序:优化边界坐标、保存、预览、关闭
        buttonPanel.add(optimizeBtn);
        buttonPanel.add(saveBtn);
        buttonPanel.add(previewBtn);
        buttonPanel.add(closeBtn);
        add(buttonPanel, BorderLayout.SOUTH);
 
        pack();
        setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
        setLocationRelativeTo(getOwner());
    }
 
    private String prepareCoordinateForEditor(String value) {
        if (value == null) {
            return "";
        }
        String trimmed = value.trim();
        if (trimmed.isEmpty() || "-1".equals(trimmed)) {
            return "";
        }
        return trimmed;
    }
 
    private JTextArea createInfoTextArea(String text, boolean editable, int rows) {
        JTextArea area = new JTextArea(text);
        area.setEditable(editable);
        area.setLineWrap(true);
        area.setWrapStyleWord(true);
        area.setFont(new Font("微软雅黑", Font.PLAIN, 13));
        area.setRows(Math.max(rows, 2));
        area.setCaretPosition(0);
        area.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6));
        area.setBackground(editable ? WHITE : new Color(245, 245, 245));
        return area;
    }
 
    private JPanel createTextAreaSection(String title, JTextArea textArea) {
        JPanel section = new JPanel(new BorderLayout(0, 6));
        section.setBackground(BACKGROUND_COLOR);
        section.setAlignmentX(Component.LEFT_ALIGNMENT);
 
        JPanel titlePanel = new JPanel(new BorderLayout());
        titlePanel.setBackground(BACKGROUND_COLOR);
        titlePanel.setOpaque(false);
 
        JLabel titleLabel = new JLabel(title);
        titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 14));
        titleLabel.setForeground(TEXT_COLOR);
        titlePanel.add(titleLabel, BorderLayout.WEST);
 
        JButton copyButton = Fuzhibutton.createCopyButton(
            () -> {
                String text = textArea.getText();
                if (text == null || text.trim().isEmpty() || "-1".equals(text.trim())) {
                    return null;
                }
                return text;
            },
            "复制",
            new Color(230, 250, 240)
        );
        copyButton.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        copyButton.setPreferredSize(new Dimension(50, 24));
        copyButton.setMargin(new Insets(0,0,0,0));
 
        titlePanel.add(copyButton, BorderLayout.EAST);
 
        section.add(titlePanel, BorderLayout.NORTH);
 
        JScrollPane scrollPane = new JScrollPane(textArea);
        scrollPane.setBorder(BorderFactory.createLineBorder(BORDER_COLOR));
        scrollPane.getVerticalScrollBar().setUnitIncrement(12);
        section.add(scrollPane, BorderLayout.CENTER);
 
        section.setBorder(BorderFactory.createEmptyBorder(4, 0, 12, 0));
        return section;
    }
 
    private JButton createPrimaryFooterButton(String text) {
        JButton button = new JButton(text);
        button.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        button.setBackground(PRIMARY_COLOR);
        button.setForeground(WHITE);
        button.setBorder(BorderFactory.createEmptyBorder(6, 12, 6, 12));
        button.setFocusPainted(false);
        button.setCursor(new Cursor(Cursor.HAND_CURSOR));
 
        button.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent e) {
                button.setBackground(PRIMARY_DARK);
            }
 
            public void mouseExited(java.awt.event.MouseEvent e) {
                button.setBackground(PRIMARY_COLOR);
            }
        });
 
        return button;
    }
    
    private String getCurrentTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(new Date());
    }
    
    /**
     * 将十进制度转换为度分格式字符串
     * 例如:39.831468 -> "3949.888080" (39度49.888080分)
     * 
     * @param decimalDegrees 十进制度
     * @return 度分格式字符串
     */
    private String decimalToDegreeMinute(double decimalDegrees) {
        double absDecimal = Math.abs(decimalDegrees);
        int degrees = (int) Math.floor(absDecimal);
        double minutes = (absDecimal - degrees) * 60.0;
        double degreeMinutes = degrees * 100.0 + minutes;
        return String.format(java.util.Locale.US, "%.8f", degreeMinutes);
    }
}