826220679@qq.com
2 天以前 48ee74129bb09a817a0bbbabe860c4007b74c66b
src/baseStation/BaseStationDialog.java
@@ -3,6 +3,7 @@
import javax.swing.*;
import gecaoji.Device;
import publicway.buttonset;
import java.awt.*;
import java.awt.event.ActionListener;
@@ -13,6 +14,7 @@
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Properties;
public class BaseStationDialog extends JDialog {
@@ -180,26 +182,24 @@
        baseStation.load();
        String currentRaw = baseStation.getInstallationCoordinates();
        String normalizedCurrent = currentRaw == null ? "-1" : currentRaw.trim();
        if (normalizedCurrent.isEmpty()) {
            normalizedCurrent = "-1";
        }
        String normalizedCurrent = canonicalizeCoordinateValue(currentRaw);
        boolean hasExistingCoordinate = normalizedCurrent != null && !"-1".equals(normalizedCurrent);
        JTextField inputField = new JTextField("-1".equals(normalizedCurrent) ? "" : normalizedCurrent);
        JTextField inputField = new JTextField(hasExistingCoordinate ? normalizedCurrent : "");
        inputField.setColumns(28);
        JPanel dialogPanel = new JPanel(new BorderLayout(0, 8));
        JLabel hintLabel = new JLabel("请输入新的基准站坐标(格式示例:2324.194945,N,11330.938547,E)");
        JLabel hintLabel = new JLabel("请输入新的基准站坐标(示例:3949.90238860,N,11616.75692000,E)");
        hintLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        dialogPanel.add(hintLabel, BorderLayout.NORTH);
        dialogPanel.add(inputField, BorderLayout.CENTER);
    JOptionPane optionPane = new JOptionPane(dialogPanel,
        JOptionPane.PLAIN_MESSAGE,
        JOptionPane.OK_CANCEL_OPTION);
    JDialog dialog = optionPane.createDialog(this, "修改基准站位置");
    dialog.setModal(true);
    dialog.pack();
        JOptionPane optionPane = new JOptionPane(dialogPanel,
            JOptionPane.PLAIN_MESSAGE,
            JOptionPane.OK_CANCEL_OPTION);
        JDialog dialog = optionPane.createDialog(this, "修改基准站位置");
        dialog.setModal(true);
        dialog.pack();
        Dimension packedSize = dialog.getSize();
        Window ownerWindow = getOwner();
@@ -208,12 +208,11 @@
            referenceWidth = 400;
        }
        dialog.setSize(new Dimension(referenceWidth, packedSize.height));
    dialog.setResizable(false);
    dialog.setLocationRelativeTo(this);
    dialog.setVisible(true);
    Object selectedValue = optionPane.getValue();
    if (!(selectedValue instanceof Integer) || ((Integer) selectedValue) != JOptionPane.OK_OPTION) {
        dialog.setResizable(false);
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
        Object selectedValue = optionPane.getValue();
        if (!(selectedValue instanceof Integer) || ((Integer) selectedValue) != JOptionPane.OK_OPTION) {
            return;
        }
@@ -234,7 +233,7 @@
            }
        }
        String valueToSave = trimmed.isEmpty() ? "-1" : trimmed;
        String valueToSave = trimmed.isEmpty() ? "-1" : canonicalizeCoordinateValue(trimmed);
        if (!"-1".equals(valueToSave) && !looksLikeCoordinateFormat(valueToSave)) {
            int confirm = JOptionPane.showConfirmDialog(this,
@@ -247,7 +246,7 @@
            }
        }
        if (valueToSave.equals(normalizedCurrent)) {
        if (normalizedCurrent.equals(valueToSave)) {
            JOptionPane.showMessageDialog(this,
                    "基准站位置未发生变化。",
                    "提示",
@@ -298,7 +297,7 @@
        titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 14));
        titleLabel.setForeground(Color.DARK_GRAY);
        JButton actionButton = createInlineButton(buttonText, buttonColor);
        JButton actionButton = buttonset.createStyledButton(buttonText, buttonColor);
        actionButton.addActionListener(actionListener);
        panel.add(titleLabel);
@@ -307,30 +306,6 @@
        return panel;
    }
    private JButton createInlineButton(String text, Color bgColor) {
        JButton button = new JButton(text);
        button.setFont(new Font("微软雅黑", Font.BOLD, 14));
        button.setBackground(bgColor);
        button.setForeground(Color.WHITE);
        button.setFocusPainted(false);
        button.setBorder(BorderFactory.createEmptyBorder(8, 18, 8, 18));
        Dimension size = new Dimension(90, 36);
        button.setPreferredSize(size);
        button.setMinimumSize(size);
        button.setMaximumSize(size);
        button.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                button.setBackground(brightenColor(bgColor));
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                button.setBackground(bgColor);
            }
        });
        return button;
    }
    
    private Color brightenColor(Color color) {
        int r = Math.min(255, color.getRed() + 30);
@@ -425,26 +400,11 @@
            return "设备没有安装固定";
        }
        String coordinates = baseStation.getInstallationCoordinates();
        if (coordinates == null) {
        String canonical = canonicalizeCoordinateValue(coordinates);
        if (canonical == null || "-1".equals(canonical)) {
            return "设备没有安装固定";
        }
        String trimmed = coordinates.trim();
        if (trimmed.isEmpty() || "-1".equals(trimmed)) {
            return "设备没有安装固定";
        }
        try {
            String[] parts = trimmed.split(",");
            if (parts.length == 4) {
                String lat = formatCoordinate(parts[0].trim(), true);
                String latDir = parts[1].trim();
                String lon = formatCoordinate(parts[2].trim(), false);
                String lonDir = parts[3].trim();
                return String.format("%s°%s, %s°%s", lat, latDir, lon, lonDir);
            }
        } catch (Exception e) {
            // ignore formatting errors and fall back to raw value
        }
        return trimmed;
        return canonical;
    }
    private String getSimCardDisplay() {
@@ -497,22 +457,93 @@
        return !trimmed.isEmpty() && !"-1".equals(trimmed);
    }
    
    private String formatCoordinate(String coordinate, boolean isLatitude) {
        // 格式化坐标:2324.194945 -> 23°24.1949'
        try {
            // 度数是前2位(纬度)或3位(经度)
            int degreeDigits = isLatitude ? 2 : 3;
            String degreeStr = coordinate.substring(0, degreeDigits);
            String minuteStr = coordinate.substring(degreeDigits);
            // 保留4位小数
            double minutes = Double.parseDouble(minuteStr);
            String formattedMinutes = String.format("%.4f", minutes);
            return degreeStr + "°" + formattedMinutes + "'";
        } catch (Exception e) {
            return coordinate;
    // Normalizes coordinate strings into degree-minute format when possible for consistent display/storage
    private String canonicalizeCoordinateValue(String value) {
        if (value == null) {
            return "-1";
        }
        String trimmed = value.trim();
        if (trimmed.isEmpty() || "-1".equals(trimmed)) {
            return "-1";
        }
        String[] parts = trimmed.split(",");
        if (parts.length != 4) {
            return trimmed;
        }
        String latDirRaw = parts[1] == null ? "" : parts[1].trim();
        String lonDirRaw = parts[3] == null ? "" : parts[3].trim();
        if (latDirRaw.isEmpty() || lonDirRaw.isEmpty()) {
            return trimmed;
        }
        String latDir = latDirRaw.toUpperCase(Locale.ROOT);
        String lonDir = lonDirRaw.toUpperCase(Locale.ROOT);
        if (!isValidDirection(latDir, true) || !isValidDirection(lonDir, false)) {
            return trimmed;
        }
        String formattedLat = convertToDegreeMinuteString(parts[0], latDir, true);
        String formattedLon = convertToDegreeMinuteString(parts[2], lonDir, false);
        if (formattedLat == null || formattedLon == null) {
            return trimmed;
        }
        return formattedLat + "," + latDir + "," + formattedLon + "," + lonDir;
    }
    private boolean isValidDirection(String direction, boolean isLatitude) {
        if (direction == null) {
            return false;
        }
        if (isLatitude) {
            return "N".equals(direction) || "S".equals(direction);
        }
        return "E".equals(direction) || "W".equals(direction);
    }
    // Converts decimal degrees or degree-minute input into a canonical degree-minute string (8 decimal places)
    private String convertToDegreeMinuteString(String rawValue, String direction, boolean isLatitude) {
        double decimal = parseCoordinateToDecimalDegrees(rawValue, direction, isLatitude);
        if (!Double.isFinite(decimal)) {
            return null;
        }
        double absDecimal = Math.abs(decimal);
        int degrees = (int) Math.floor(absDecimal);
        double minutes = (absDecimal - degrees) * 60.0d;
        double degreeMinutes = degrees * 100.0d + minutes;
        return String.format(Locale.US, "%.8f", degreeMinutes);
    }
    private double parseCoordinateToDecimalDegrees(String rawValue, String direction, boolean isLatitude) {
        if (rawValue == null) {
            return Double.NaN;
        }
        String trimmed = rawValue.trim();
        if (trimmed.isEmpty()) {
            return Double.NaN;
        }
        double numeric;
        try {
            numeric = Double.parseDouble(trimmed);
        } catch (NumberFormatException ex) {
            return Double.NaN;
        }
        double abs = Math.abs(numeric);
        double boundary = isLatitude ? 90d : 180d;
        double decimal;
        if (abs <= boundary) {
            decimal = abs;
        } else {
            double degrees = Math.floor(abs / 100d);
            double minutes = abs - degrees * 100d;
            decimal = degrees + minutes / 60d;
        }
        String dirUpper = direction == null ? "" : direction.trim().toUpperCase(Locale.ROOT);
        if ("S".equals(dirUpper) || "W".equals(dirUpper)) {
            decimal = -decimal;
        } else if (!"N".equals(dirUpper) && !"E".equals(dirUpper) && numeric < 0d) {
            decimal = -decimal;
        }
        return decimal;
    }
    
    private void lockBaseStationPosition() {
@@ -542,7 +573,7 @@
                JOptionPane.INFORMATION_MESSAGE);
            
            // 更新基准站位置(这里使用模拟数据,实际应从GPS获取)
            String newPosition = "2324.194945,N,11330.938547,E";
            String newPosition = canonicalizeCoordinateValue("2324.194945,N,11330.938547,E");
            String timestamp = String.valueOf(System.currentTimeMillis());
            if (!hasBaseStationId()) {