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);
|
}
|
}
|