Просмотр исходного кода

添加角度格式选择、展示数据分页,新增水准测段高差正常水准面不平行改正工具

qyx 3 дней назад
Родитель
Сommit
2a778bc8bc
29 измененных файлов: 3882 добавлений и 183 удалений
  1. 303
    0
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/controller/CmcNonparallelismCorrectionController.java
  2. 16
    3
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/domain/CmcGaussNegative.java
  3. 16
    3
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/domain/CmcGaussPositive.java
  4. 13
    0
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/domain/CmcGeodeticToSpatial.java
  5. 511
    0
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/domain/CmcNonparallelismCorrection.java
  6. 13
    0
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/domain/CmcSpatialToGeodetic.java
  7. 16
    3
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/domain/CmcUTMNegative.java
  8. 18
    3
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/domain/CmcUTMPositive.java
  9. 48
    0
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/ICmcNonparallelismCorrectionService.java
  10. 22
    11
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/impl/CmcGaussNegativeServiceImpl.java
  11. 39
    6
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/impl/CmcGaussPositiveServiceImpl.java
  12. 11
    5
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/impl/CmcGeodeticToSpatialServiceImpl.java
  13. 785
    0
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/impl/CmcNonparallelismCorrectionServiceImpl.java
  14. 40
    15
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/impl/CmcSpatialToGeodeticServiceImpl.java
  15. 11
    4
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/impl/CmcUTMNegativeServiceImpl.java
  16. 40
    8
      oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/impl/CmcUTMPositiveServiceImpl.java
  17. 63
    0
      oa-ui/src/api/calculate/nonparallelismcorrection.js
  18. 7
    1
      oa-ui/src/views/calculate/index.vue
  19. 54
    9
      oa-ui/src/views/calculate/tools/DMStodegree.vue
  20. 54
    9
      oa-ui/src/views/calculate/tools/degreetoDMS.vue
  21. 54
    3
      oa-ui/src/views/calculate/tools/degreetoradian.vue
  22. 58
    7
      oa-ui/src/views/calculate/tools/gaussbandchange.vue
  23. 71
    9
      oa-ui/src/views/calculate/tools/gaussnegative.vue
  24. 74
    10
      oa-ui/src/views/calculate/tools/gausspositive.vue
  25. 67
    5
      oa-ui/src/views/calculate/tools/geodetictospatial.vue
  26. 1238
    0
      oa-ui/src/views/calculate/tools/nonparallelismcorrection.vue
  27. 89
    27
      oa-ui/src/views/calculate/tools/spatialtogeodetic.vue
  28. 67
    12
      oa-ui/src/views/calculate/tools/utmnegative.vue
  29. 84
    30
      oa-ui/src/views/calculate/tools/utmpositive.vue

+ 303
- 0
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/controller/CmcNonparallelismCorrectionController.java Просмотреть файл

@@ -0,0 +1,303 @@
1
+package com.ruoyi.web.calculate.controller;
2
+
3
+import java.io.IOException;
4
+import java.io.OutputStream;
5
+import java.util.ArrayList;
6
+import java.util.List;
7
+import java.util.Map;
8
+import javax.servlet.http.HttpServletResponse;
9
+
10
+import org.apache.poi.ss.util.CellRangeAddress;
11
+
12
+import org.springframework.beans.factory.annotation.Autowired;
13
+import org.springframework.web.bind.annotation.GetMapping;
14
+import org.springframework.web.bind.annotation.PostMapping;
15
+import org.springframework.web.bind.annotation.PutMapping;
16
+import org.springframework.web.bind.annotation.DeleteMapping;
17
+import org.springframework.web.bind.annotation.PathVariable;
18
+import org.springframework.web.bind.annotation.RequestBody;
19
+import org.springframework.web.bind.annotation.RequestMapping;
20
+import org.springframework.web.bind.annotation.RequestParam;
21
+import org.springframework.web.bind.annotation.RestController;
22
+import org.springframework.web.multipart.MultipartFile;
23
+
24
+import com.ruoyi.common.annotation.Log;
25
+import com.ruoyi.common.core.controller.BaseController;
26
+import com.ruoyi.common.core.domain.AjaxResult;
27
+import com.ruoyi.common.enums.BusinessType;
28
+import com.ruoyi.web.calculate.domain.CmcNonparallelismCorrection;
29
+import com.ruoyi.web.calculate.service.ICmcNonparallelismCorrectionService;
30
+import com.ruoyi.common.utils.poi.ExcelUtil;
31
+import com.ruoyi.common.core.page.TableDataInfo;
32
+
33
+import org.apache.poi.ss.usermodel.*;
34
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
35
+import com.fasterxml.jackson.core.type.TypeReference;
36
+import com.fasterxml.jackson.databind.ObjectMapper;
37
+
38
+/**
39
+ * 非平行差改正Controller
40
+ * 
41
+ * @author qyx
42
+ * @date 2026-06-22
43
+ */
44
+@RestController
45
+@RequestMapping("/calculate/nonparallelismCorrection")
46
+public class CmcNonparallelismCorrectionController extends BaseController
47
+{
48
+    @Autowired
49
+    private ICmcNonparallelismCorrectionService cmcNonparallelismCorrectionService;
50
+
51
+     /**
52
+     * 导入Excel数据(支持多个工作表)
53
+     * 
54
+     * @param file           Excel文件
55
+     * @param sheetNames     工作表名称列表(可选,为空时读取所有工作表)
56
+     * @param columnMappings 列映射配置(可选)
57
+     */
58
+    @PostMapping("/import")
59
+    public AjaxResult importExcel(@RequestParam("file") MultipartFile file,
60
+            @RequestParam(value = "sheetNames", required = false) List<String> sheetNames,
61
+            @RequestParam(value = "columnMappings", required = false) String columnMappings) {
62
+        try {
63
+            // 检查文件是否为空
64
+            if (file.isEmpty()) {
65
+                return AjaxResult.error("请选择要导入的文件!");
66
+            }
67
+
68
+            // 检查文件格式
69
+            String fileName = file.getOriginalFilename();
70
+            if (fileName == null || (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx"))) {
71
+                return AjaxResult.error("请上传Excel文件(.xls或.xlsx格式)!");
72
+            }
73
+
74
+            // 调用Service层解析Excel并返回数据
75
+            return cmcNonparallelismCorrectionService.importExcelData(file, sheetNames, columnMappings);
76
+
77
+        } catch (Exception e) {
78
+            e.printStackTrace();
79
+            return AjaxResult.error("导入失败:" + e.getMessage());
80
+        }
81
+    }
82
+
83
+    /**
84
+     * 导出非平行差改正列表(两个表在同一个Excel文件的两个sheet中)
85
+     */
86
+    @Log(title = "非平行差改正", businessType = BusinessType.EXPORT)
87
+    @PostMapping("/export")
88
+    public void export(HttpServletResponse response, @RequestBody Map<String, Object> exportData)
89
+    {
90
+        try {
91
+            ObjectMapper objectMapper = new ObjectMapper();
92
+            
93
+            // 解析测段高差表数据
94
+            List<CmcNonparallelismCorrection> heightDifferenceData = objectMapper.convertValue(
95
+                exportData.get("heightDifferenceData"),
96
+                new TypeReference<List<CmcNonparallelismCorrection>>() {}
97
+            );
98
+            
99
+            // 解析不平行改正表数据
100
+            List<CmcNonparallelismCorrection> correctionData = objectMapper.convertValue(
101
+                exportData.get("correctionData"),
102
+                new TypeReference<List<CmcNonparallelismCorrection>>() {}
103
+            );
104
+            
105
+            // 创建Excel工作簿
106
+            Workbook workbook = new XSSFWorkbook();
107
+            
108
+            // 创建测段高差表sheet
109
+            createHeightDifferenceSheet(workbook, heightDifferenceData);
110
+            
111
+            // 创建不平行改正表sheet
112
+            createCorrectionSheet(workbook, correctionData);
113
+            
114
+            // 设置响应头
115
+            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
116
+            response.setHeader("Content-Disposition", "attachment; filename=非平行差改正结果.xlsx");
117
+            
118
+            // 写入响应流
119
+            OutputStream outputStream = response.getOutputStream();
120
+            workbook.write(outputStream);
121
+            outputStream.flush();
122
+            outputStream.close();
123
+            workbook.close();
124
+            
125
+        } catch (Exception e) {
126
+            e.printStackTrace();
127
+            throw new RuntimeException("导出失败:" + e.getMessage());
128
+        }
129
+    }
130
+    
131
+    /**
132
+     * 创建测段高差表sheet
133
+     */
134
+    private void createHeightDifferenceSheet(Workbook workbook, List<CmcNonparallelismCorrection> dataList) {
135
+        Sheet sheet = workbook.createSheet("测段高差表");
136
+        
137
+        // 创建表头样式
138
+        CellStyle headerStyle = workbook.createCellStyle();
139
+        Font headerFont = workbook.createFont();
140
+        headerFont.setBold(true);
141
+        headerStyle.setFont(headerFont);
142
+        headerStyle.setAlignment(HorizontalAlignment.CENTER);
143
+        headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
144
+        headerStyle.setBorderBottom(BorderStyle.THIN);
145
+        headerStyle.setBorderTop(BorderStyle.THIN);
146
+        headerStyle.setBorderLeft(BorderStyle.THIN);
147
+        headerStyle.setBorderRight(BorderStyle.THIN);
148
+        
149
+        // 创建数据样式
150
+        CellStyle dataStyle = workbook.createCellStyle();
151
+        dataStyle.setAlignment(HorizontalAlignment.CENTER);
152
+        dataStyle.setVerticalAlignment(VerticalAlignment.CENTER);
153
+        dataStyle.setBorderBottom(BorderStyle.THIN);
154
+        dataStyle.setBorderTop(BorderStyle.THIN);
155
+        dataStyle.setBorderLeft(BorderStyle.THIN);
156
+        dataStyle.setBorderRight(BorderStyle.THIN);
157
+        
158
+        // 创建表头行
159
+        Row headerRow = sheet.createRow(0);
160
+        String[] headers = {"序号", "起点号", "终点号", "站数", "距离(m)", "高差值(m)", 
161
+                           "标尺真长(m)", "平均距离(km)", "平均尺改高差(m)", "往返较差(mm)", "限差(mm)", "精度统计", "质量评分"};
162
+        for (int i = 0; i < headers.length; i++) {
163
+            Cell cell = headerRow.createCell(i);
164
+            cell.setCellValue(headers[i]);
165
+            cell.setCellStyle(headerStyle);
166
+            sheet.setColumnWidth(i, 4000);
167
+        }
168
+        
169
+        // 填充数据
170
+        if (dataList != null && !dataList.isEmpty()) {
171
+            for (int i = 0; i < dataList.size(); i++) {
172
+                Row row = sheet.createRow(i + 1);
173
+                CmcNonparallelismCorrection item = dataList.get(i);
174
+                
175
+                // 序号(每两行显示一个序号)
176
+                createCell(row, 0, Math.floor(i / 2) + 1, dataStyle);
177
+                createCell(row, 1, item.getStartPointNo(), dataStyle);
178
+                createCell(row, 2, item.getEndPointNo(), dataStyle);
179
+                createCell(row, 3, item.getStationCount(), dataStyle);
180
+                createCell(row, 4, item.getDistance(), dataStyle);
181
+                createCell(row, 5, item.getHeightDifference(), dataStyle);
182
+                createCell(row, 6, item.getScaleTrueLength(), dataStyle);
183
+                createCell(row, 7, item.getAverageDistance(), dataStyle);
184
+                createCell(row, 8, item.getAverageScaleCorrectedHeightDiff(), dataStyle);
185
+                createCell(row, 9, item.getRoundTripDifference(), dataStyle);
186
+                createCell(row, 10, item.getTolerance(), dataStyle);
187
+                createCell(row, 11, item.getPrecisionStatistics(), dataStyle);
188
+                createCell(row, 12, item.getQualityScore(), dataStyle);
189
+            }
190
+            
191
+            // 合并单元格:每两行合并一次
192
+            // 需要合并的列索引:0: 序号, 7: 平均距离(km), 8: 平均尺改高差(m), 9: 往返较差(mm), 10: 限差(mm), 11: 精度统计, 12: 质量评分
193
+            int[] mergeColumns = {0, 7, 8, 9, 10, 11, 12};
194
+            for (int i = 0; i < dataList.size(); i += 2) {
195
+                for (int colIndex : mergeColumns) {
196
+                    if (i + 1 < dataList.size()) {
197
+                        // 合并当前行和下一行
198
+                        sheet.addMergedRegion(new CellRangeAddress(i + 1, i + 2, colIndex, colIndex));
199
+                    }
200
+                }
201
+            }
202
+        }
203
+    }
204
+    
205
+    /**
206
+     * 创建不平行改正表sheet
207
+     */
208
+    private void createCorrectionSheet(Workbook workbook, List<CmcNonparallelismCorrection> dataList) {
209
+        Sheet sheet = workbook.createSheet("不平行改正表");
210
+        
211
+        // 创建表头样式
212
+        CellStyle headerStyle = workbook.createCellStyle();
213
+        Font headerFont = workbook.createFont();
214
+        headerFont.setBold(true);
215
+        headerStyle.setFont(headerFont);
216
+        headerStyle.setAlignment(HorizontalAlignment.CENTER);
217
+        headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
218
+        headerStyle.setBorderBottom(BorderStyle.THIN);
219
+        headerStyle.setBorderTop(BorderStyle.THIN);
220
+        headerStyle.setBorderLeft(BorderStyle.THIN);
221
+        headerStyle.setBorderRight(BorderStyle.THIN);
222
+        
223
+        // 创建数据样式
224
+        CellStyle dataStyle = workbook.createCellStyle();
225
+        dataStyle.setAlignment(HorizontalAlignment.CENTER);
226
+        dataStyle.setVerticalAlignment(VerticalAlignment.CENTER);
227
+        dataStyle.setBorderBottom(BorderStyle.THIN);
228
+        dataStyle.setBorderTop(BorderStyle.THIN);
229
+        dataStyle.setBorderLeft(BorderStyle.THIN);
230
+        dataStyle.setBorderRight(BorderStyle.THIN);
231
+        
232
+        // 创建表头行
233
+        Row headerRow = sheet.createRow(0);
234
+        String[] headers = {"待求点", "纵坐标X(m)", "横坐标Y(m)", "高程H(m)", "带号", "带宽(°)",
235
+                           "大地经度(°′″)", "大地纬度(°′″)", "点间改正ε(m)", "改正后高差(m)", "高程(m)",
236
+                           "距起点距离(m)", "高程中误差(m)"};
237
+        for (int i = 0; i < headers.length; i++) {
238
+            Cell cell = headerRow.createCell(i);
239
+            cell.setCellValue(headers[i]);
240
+            cell.setCellStyle(headerStyle);
241
+            sheet.setColumnWidth(i, 5000);
242
+        }
243
+        
244
+        // 填充数据
245
+        if (dataList != null && !dataList.isEmpty()) {
246
+            for (int i = 0; i < dataList.size(); i++) {
247
+                Row row = sheet.createRow(i + 1);
248
+                CmcNonparallelismCorrection item = dataList.get(i);
249
+                
250
+                createCell(row, 0, item.getPendingPoint(), dataStyle);
251
+                createCell(row, 1, item.getCoordinateX(), dataStyle);
252
+                createCell(row, 2, item.getCoordinateY(), dataStyle);
253
+                createCell(row, 3, item.getHeightH(), dataStyle);
254
+                createCell(row, 4, item.getZoneNo(), dataStyle);
255
+                createCell(row, 5, item.getBandWidth(), dataStyle);
256
+                createCell(row, 6, item.getGeodeticLongitude(), dataStyle);
257
+                createCell(row, 7, item.getGeodeticLatitude(), dataStyle);
258
+                createCell(row, 8, item.getPointCorrection(), dataStyle);
259
+                createCell(row, 9, item.getCorrectedHeightDifference(), dataStyle);
260
+                createCell(row, 10, item.getElevation(), dataStyle);
261
+                createCell(row, 11, item.getDistanceFromStart(), dataStyle);
262
+                createCell(row, 12, item.getHeightMiddleError(), dataStyle);
263
+            }
264
+            
265
+            // 合并单元格:每两行合并一次
266
+            // 需要合并的列索引:8: 点间改正ε(m), 9: 改正后高差(m)
267
+            int[] mergeColumns = {8, 9};
268
+            for (int i = 0; i < dataList.size(); i += 2) {
269
+                for (int colIndex : mergeColumns) {
270
+                    if (i + 1 < dataList.size()) {
271
+                        // 合并当前行和下一行
272
+                        sheet.addMergedRegion(new CellRangeAddress(i + 1, i + 2, colIndex, colIndex));
273
+                    }
274
+                }
275
+            }
276
+        }
277
+    }
278
+    
279
+    /**
280
+     * 创建单元格并设置值
281
+     */
282
+    private void createCell(Row row, int column, Object value, CellStyle style) {
283
+        Cell cell = row.createCell(column);
284
+        if (value == null) {
285
+            cell.setCellValue("");
286
+        } else if (value instanceof Number) {
287
+            cell.setCellValue(((Number) value).doubleValue());
288
+        } else {
289
+            cell.setCellValue(value.toString());
290
+        }
291
+        cell.setCellStyle(style);
292
+    }
293
+
294
+    /**
295
+     * 执行非平行差改正计算(仅计算,不保存)
296
+     */
297
+    @PostMapping("/calculate")
298
+    public AjaxResult calculate(@RequestBody List<CmcNonparallelismCorrection> dataList)
299
+    {
300
+        List<CmcNonparallelismCorrection> result = cmcNonparallelismCorrectionService.calculateNonparallelismCorrection(dataList);
301
+        return success(result);
302
+    }
303
+}

+ 16
- 3
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/domain/CmcGaussNegative.java Просмотреть файл

@@ -36,7 +36,7 @@ public class CmcGaussNegative extends BaseEntity {
36 36
     
37 37
     /** 带号 */
38 38
     @Excel(name = "带号", cellType = ColumnType.NUMERIC)
39
-    private Integer band;
39
+    private Double band;
40 40
 
41 41
     /** 带宽 */
42 42
     @Excel(name = "带宽", cellType = ColumnType.NUMERIC)
@@ -62,6 +62,9 @@ public class CmcGaussNegative extends BaseEntity {
62 62
     @Excel(name = "投影面高程", cellType = ColumnType.NUMERIC)
63 63
     private double projectionHeight;
64 64
 
65
+    /** 输出格式:degree(度) / dms(度分秒) */
66
+    private String outputFormat;
67
+
65 68
 
66 69
     public void setId(Long id) 
67 70
     {
@@ -142,12 +145,12 @@ public class CmcGaussNegative extends BaseEntity {
142 145
         return latitudePosition;
143 146
     }
144 147
     
145
-    public void setBand(Integer band) 
148
+    public void setBand(Double band) 
146 149
     {
147 150
         this.band = band;
148 151
     }
149 152
 
150
-    public Integer getBand() 
153
+    public Double getBand() 
151 154
     {
152 155
         return band;
153 156
     }
@@ -172,6 +175,16 @@ public class CmcGaussNegative extends BaseEntity {
172 175
         return projectionHeight;
173 176
     }
174 177
     
178
+    public void setOutputFormat(String outputFormat) 
179
+    {
180
+        this.outputFormat = outputFormat;
181
+    }
182
+
183
+    public String getOutputFormat() 
184
+    {
185
+        return outputFormat;
186
+    }
187
+    
175 188
     public void setGaussX(Double gaussX) 
176 189
     {
177 190
         this.gaussX = gaussX;

+ 16
- 3
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/domain/CmcGaussPositive.java Просмотреть файл

@@ -48,7 +48,7 @@ public class CmcGaussPositive extends BaseEntity
48 48
 
49 49
     /** 带号 */
50 50
     @Excel(name = "带号", cellType = ColumnType.NUMERIC)
51
-    private Integer band;
51
+    private double band;
52 52
 
53 53
     /** 带宽 */
54 54
     @Excel(name = "带宽", cellType = ColumnType.NUMERIC)
@@ -58,6 +58,9 @@ public class CmcGaussPositive extends BaseEntity
58 58
     @Excel(name = "投影面高程", cellType = ColumnType.NUMERIC)
59 59
     private double projectionHeight;
60 60
 
61
+    /** 角度格式:degree(度) / dms(度分秒) */
62
+    private String angleFormat;
63
+
61 64
     /** 高斯坐标x */
62 65
     @Excel(name = "高斯坐标x", cellType = ColumnType.NUMERIC, numberFormat = "0.0000")
63 66
     private Double gaussX;
@@ -149,12 +152,12 @@ public class CmcGaussPositive extends BaseEntity
149 152
         return latitudePosition;
150 153
     }
151 154
     
152
-    public void setBand(Integer band) 
155
+    public void setBand(double band) 
153 156
     {
154 157
         this.band = band;
155 158
     }
156 159
 
157
-    public Integer getBand() 
160
+    public double getBand() 
158 161
     {
159 162
         return band;
160 163
     }
@@ -179,6 +182,16 @@ public class CmcGaussPositive extends BaseEntity
179 182
         return projectionHeight;
180 183
     }
181 184
     
185
+    public void setAngleFormat(String angleFormat) 
186
+    {
187
+        this.angleFormat = angleFormat;
188
+    }
189
+
190
+    public String getAngleFormat() 
191
+    {
192
+        return angleFormat;
193
+    }
194
+    
182 195
     public void setGaussX(Double gaussX) 
183 196
     {
184 197
         this.gaussX = gaussX;

+ 13
- 0
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/domain/CmcGeodeticToSpatial.java Просмотреть файл

@@ -65,6 +65,9 @@ public class CmcGeodeticToSpatial extends BaseEntity
65 65
     @Excel(name = "投影面高程", cellType = ColumnType.NUMERIC)
66 66
     private double projectionHeight;
67 67
 
68
+    /** 角度格式:degree(度) / dms(度分秒) */
69
+    private String angleFormat;
70
+
68 71
     public void setId(Long id) 
69 72
     {
70 73
         this.id = id;
@@ -202,6 +205,16 @@ public class CmcGeodeticToSpatial extends BaseEntity
202 205
     {
203 206
         return projectionHeight;
204 207
     }
208
+    
209
+    public void setAngleFormat(String angleFormat) 
210
+    {
211
+        this.angleFormat = angleFormat;
212
+    }
213
+
214
+    public String getAngleFormat() 
215
+    {
216
+        return angleFormat;
217
+    }
205 218
 
206 219
     @Override
207 220
     public String toString() {

+ 511
- 0
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/domain/CmcNonparallelismCorrection.java Просмотреть файл

@@ -0,0 +1,511 @@
1
+package com.ruoyi.web.calculate.domain;
2
+
3
+import java.math.BigDecimal;
4
+import java.math.RoundingMode;
5
+
6
+import org.apache.commons.lang3.builder.ToStringBuilder;
7
+import org.apache.commons.lang3.builder.ToStringStyle;
8
+import com.ruoyi.common.annotation.Excel;
9
+import com.ruoyi.common.annotation.Excel.ColumnType;
10
+import com.ruoyi.common.core.domain.BaseEntity;
11
+
12
+/**
13
+ * 非平行差改正计算对象 cmc_nonparallelism_correction
14
+ * 
15
+ * @author qyx
16
+ * @date 2026-06-22
17
+ */
18
+public class CmcNonparallelismCorrection extends BaseEntity
19
+{
20
+    private static final long serialVersionUID = 1L;
21
+
22
+    /** 主键ID */
23
+    private Long id;
24
+
25
+    /** 起点号 */
26
+    @Excel(name = "起点号")
27
+    private String startPointNo;
28
+
29
+    /** 终点号 */
30
+    @Excel(name = "终点号")
31
+    private String endPointNo;
32
+
33
+    /** 站数 */
34
+    @Excel(name = "站数", cellType = ColumnType.NUMERIC)
35
+    private Integer stationCount;
36
+
37
+    /** 距离(m) */
38
+    @Excel(name = "距离(m)", cellType = ColumnType.NUMERIC, numberFormat = "0.000000")
39
+    private Double distance;
40
+
41
+    /** 高差值(m) */
42
+    @Excel(name = "高差值(m)", cellType = ColumnType.NUMERIC, numberFormat = "0.000000")
43
+    private Double heightDifference;
44
+
45
+    /** 标尺真长(m) */
46
+    @Excel(name = "标尺真长(m)", cellType = ColumnType.NUMERIC, numberFormat = "0.000000")
47
+    private Double scaleTrueLength;
48
+
49
+    /** 平均距离(km) */
50
+    @Excel(name = "平均距离(km)", cellType = ColumnType.NUMERIC, numberFormat = "0.000000")
51
+    private Double averageDistance;
52
+
53
+    /** 尺改高差(m) */
54
+    @Excel(name = "尺改高差(m)", cellType = ColumnType.NUMERIC, numberFormat = "0.000000")
55
+    private Double scaleCorrectedHeightDiff;
56
+
57
+    /** 平均尺改高差(m) */
58
+    @Excel(name = "平均尺改高差(m)", cellType = ColumnType.NUMERIC, numberFormat = "0.000000")
59
+    private Double averageScaleCorrectedHeightDiff;
60
+
61
+    /** 往返较差(mm) */
62
+    @Excel(name = "往返较差(mm)", cellType = ColumnType.NUMERIC, numberFormat = "0.000")
63
+    private Double roundTripDifference;
64
+
65
+    /** 限差(mm) */
66
+    @Excel(name = "限差(mm)", cellType = ColumnType.NUMERIC, numberFormat = "0.000")
67
+    private Double tolerance;
68
+
69
+    /** 精度统计 */
70
+    @Excel(name = "精度统计", cellType = ColumnType.NUMERIC, numberFormat = "0.000")
71
+    private double precisionStatistics;
72
+
73
+    /** 质量评分 */
74
+    @Excel(name = "质量评分", cellType = ColumnType.NUMERIC, numberFormat = "0.00")
75
+    private Double qualityScore;
76
+
77
+    /** 待求点 */
78
+    @Excel(name = "待求点")
79
+    private String pendingPoint;
80
+
81
+    /** 纵坐标X(m) */
82
+    @Excel(name = "纵坐标X(m)", cellType = ColumnType.NUMERIC, numberFormat = "0.000000")
83
+    private Double coordinateX;
84
+
85
+    /** 横坐标Y(m) */
86
+    @Excel(name = "横坐标Y(m)", cellType = ColumnType.NUMERIC, numberFormat = "0.000000")
87
+    private Double coordinateY;
88
+
89
+    /** 高程H(m) */
90
+    @Excel(name = "高程H(m)", cellType = ColumnType.NUMERIC, numberFormat = "0.000000")
91
+    private Double heightH;
92
+
93
+    /** 坐标系 */
94
+    @Excel(name = "坐标系")
95
+    private String coordinateSystem;
96
+
97
+    /** 带号 */
98
+    @Excel(name = "带号", cellType = ColumnType.NUMERIC)
99
+    private Double zoneNo;
100
+
101
+    /** 带宽(°) */
102
+    @Excel(name = "带宽(°)", cellType = ColumnType.NUMERIC, numberFormat = "0.0")
103
+    private Double bandWidth;
104
+
105
+    /** 大地经度(° ′ ″) */
106
+    @Excel(name = "大地经度(° ′ ″)")
107
+    private double geodeticLongitude;
108
+
109
+    /** 大地纬度(° ′ ″) */
110
+    @Excel(name = "大地纬度(° ′ ″)")
111
+    private double geodeticLatitude;
112
+
113
+    /** 点间改正ε(m) */
114
+    @Excel(name = "点间改正ε(m)", cellType = ColumnType.NUMERIC, numberFormat = "0.000000")
115
+    private Double pointCorrection;
116
+
117
+    /** 改正后高差(m) */
118
+    @Excel(name = "改正后高差(m)", cellType = ColumnType.NUMERIC, numberFormat = "0.000000")
119
+    private Double correctedHeightDifference;
120
+
121
+    /** 高程(m) */
122
+    @Excel(name = "高程(m)", cellType = ColumnType.NUMERIC, numberFormat = "0.000000")
123
+    private Double elevation;
124
+
125
+    /** 起点距(km) */
126
+    @Excel(name = "起点距(km)", cellType = ColumnType.NUMERIC, numberFormat = "0.000000")
127
+    private Double distanceFromStart;
128
+
129
+    /** 高程中误差(mm) */
130
+    @Excel(name = "高程中误差(mm)", cellType = ColumnType.NUMERIC, numberFormat = "0.000")
131
+    private Double heightMiddleError;
132
+
133
+    /** 水准等级 */
134
+    @Excel(name = "水准等级", cellType = ColumnType.NUMERIC)
135
+    private int level;
136
+
137
+    /** 纬度位置 */
138
+    @Excel(name = "纬度位置")
139
+    private String latitudePosition;
140
+
141
+    /** 经度位置 */
142
+    @Excel(name = "经度位置")
143
+    private String longitudePosition;
144
+
145
+    /**投影面高程(m) */
146
+    @Excel(name = "投影面高程(m)", cellType = ColumnType.NUMERIC, numberFormat = "0.000000")
147
+    private Double projectionHeight;
148
+
149
+    public void setId(Long id) 
150
+    {
151
+        this.id = id;
152
+    }
153
+
154
+    public Long getId() 
155
+    {
156
+        return id;
157
+    }
158
+    
159
+    public void setStartPointNo(String startPointNo) 
160
+    {
161
+        this.startPointNo = startPointNo;
162
+    }
163
+
164
+    public String getStartPointNo() 
165
+    {
166
+        return startPointNo;
167
+    }
168
+
169
+    public void setEndPointNo(String endPointNo) 
170
+    {
171
+        this.endPointNo = endPointNo;
172
+    }
173
+
174
+    public String getEndPointNo() 
175
+    {
176
+        return endPointNo;
177
+    }
178
+
179
+    public void setStationCount(Integer stationCount) 
180
+    {
181
+        this.stationCount = stationCount;
182
+    }
183
+
184
+    public Integer getStationCount() 
185
+    {
186
+        return stationCount;
187
+    }
188
+
189
+    public void setDistance(Double distance) 
190
+    {
191
+        this.distance = distance;
192
+    }
193
+
194
+    public Double getDistance() 
195
+    {
196
+        return distance;
197
+    }
198
+
199
+    public void setHeightDifference(Double heightDifference) 
200
+    {
201
+        this.heightDifference = heightDifference;
202
+    }
203
+
204
+    public Double getHeightDifference() 
205
+    {
206
+        return heightDifference;
207
+    }
208
+
209
+    public void setScaleTrueLength(Double scaleTrueLength) 
210
+    {
211
+        this.scaleTrueLength = scaleTrueLength;
212
+    }
213
+
214
+    public Double getScaleTrueLength() 
215
+    {
216
+        return scaleTrueLength;
217
+    }
218
+
219
+    public void setAverageDistance(Double averageDistance) 
220
+    {
221
+        this.averageDistance = averageDistance;
222
+    }
223
+
224
+    public Double getAverageDistance() 
225
+    {
226
+        return averageDistance;
227
+    }
228
+
229
+    public void setScaleCorrectedHeightDiff(Double scaleCorrectedHeightDiff) 
230
+    {
231
+        this.scaleCorrectedHeightDiff = scaleCorrectedHeightDiff;
232
+    }
233
+
234
+    public Double getScaleCorrectedHeightDiff() 
235
+    {
236
+        return scaleCorrectedHeightDiff;
237
+    }
238
+
239
+    public void setAverageScaleCorrectedHeightDiff(Double averageScaleCorrectedHeightDiff) 
240
+    {
241
+        this.averageScaleCorrectedHeightDiff = averageScaleCorrectedHeightDiff;
242
+    }
243
+
244
+    public Double getAverageScaleCorrectedHeightDiff() 
245
+    {
246
+        return averageScaleCorrectedHeightDiff;
247
+    }
248
+
249
+    public void setRoundTripDifference(Double roundTripDifference) 
250
+    {
251
+        this.roundTripDifference = roundTripDifference;
252
+    }
253
+
254
+    public Double getRoundTripDifference() 
255
+    {
256
+        return roundTripDifference;
257
+    }
258
+
259
+    public void setTolerance(Double tolerance) 
260
+    {
261
+        this.tolerance = tolerance;
262
+    }
263
+
264
+    public Double getTolerance() 
265
+    {
266
+        return tolerance;
267
+    }
268
+
269
+    public void setPrecisionStatistics(double precisionStatistics) 
270
+    {
271
+        this.precisionStatistics = precisionStatistics;
272
+    }
273
+
274
+    public double getPrecisionStatistics() 
275
+    {
276
+        return precisionStatistics;
277
+    }
278
+
279
+    public void setQualityScore(Double qualityScore) 
280
+    {
281
+        this.qualityScore = qualityScore;
282
+    }
283
+
284
+    public Double getQualityScore() 
285
+    {
286
+        return qualityScore;
287
+    }
288
+
289
+    public void setPendingPoint(String pendingPoint) 
290
+    {
291
+        this.pendingPoint = pendingPoint;
292
+    }
293
+
294
+    public String getPendingPoint() 
295
+    {
296
+        return pendingPoint;
297
+    }
298
+
299
+    public void setCoordinateX(Double coordinateX) 
300
+    {
301
+        this.coordinateX = coordinateX;
302
+    }
303
+
304
+    public Double getCoordinateX() 
305
+    {
306
+        return coordinateX;
307
+    }
308
+
309
+    public void setCoordinateY(Double coordinateY) 
310
+    {
311
+        this.coordinateY = coordinateY;
312
+    }
313
+
314
+    public Double getCoordinateY() 
315
+    {
316
+        return coordinateY;
317
+    }
318
+
319
+    public void setHeightH(Double heightH) 
320
+    {
321
+        this.heightH = heightH;
322
+    }
323
+
324
+    public Double getHeightH() 
325
+    {
326
+        return heightH;
327
+    }
328
+
329
+    public void setCoordinateSystem(String coordinateSystem) 
330
+    {
331
+        this.coordinateSystem = coordinateSystem;
332
+    }
333
+
334
+    public String getCoordinateSystem() 
335
+    {
336
+        return coordinateSystem;
337
+    }
338
+
339
+    public void setZoneNo(Double zoneNo) 
340
+    {
341
+        this.zoneNo = zoneNo;
342
+    }
343
+
344
+    public Double getZoneNo() 
345
+    {
346
+        return zoneNo;
347
+    }
348
+
349
+    public void setBandWidth(Double bandWidth) 
350
+    {
351
+        this.bandWidth = bandWidth;
352
+    }
353
+
354
+    public Double getBandWidth() 
355
+    {
356
+        return bandWidth;
357
+    }
358
+
359
+    public void setGeodeticLongitude(double geodeticLongitude) 
360
+    {
361
+        this.geodeticLongitude = geodeticLongitude;
362
+    }
363
+
364
+    public double getGeodeticLongitude() 
365
+    {
366
+        return geodeticLongitude;
367
+    }
368
+
369
+    public void setGeodeticLatitude(double geodeticLatitude) 
370
+    {
371
+        this.geodeticLatitude = geodeticLatitude;
372
+    }
373
+
374
+    public double getGeodeticLatitude() 
375
+    {
376
+        return geodeticLatitude;
377
+    }
378
+
379
+    public void setPointCorrection(double pointCorrection) 
380
+    {
381
+        this.pointCorrection = pointCorrection;
382
+    }
383
+
384
+    public Double getPointCorrection() 
385
+    {
386
+        return pointCorrection;
387
+    }
388
+
389
+    public void setCorrectedHeightDifference(Double correctedHeightDifference) 
390
+    {
391
+        this.correctedHeightDifference = correctedHeightDifference;
392
+    }
393
+
394
+    public Double getCorrectedHeightDifference() 
395
+    {
396
+        return correctedHeightDifference;
397
+    }
398
+
399
+    public void setElevation(Double elevation) 
400
+    {
401
+        this.elevation = elevation;
402
+    }
403
+
404
+    public Double getElevation() 
405
+    {
406
+        return elevation;
407
+    }
408
+
409
+    public void setDistanceFromStart(Double distanceFromStart) 
410
+    {
411
+        this.distanceFromStart = distanceFromStart;
412
+    }
413
+
414
+    public Double getDistanceFromStart() 
415
+    {
416
+        return distanceFromStart;
417
+    }
418
+
419
+    public void setHeightMiddleError(Double heightMiddleError) 
420
+    {
421
+        this.heightMiddleError = heightMiddleError;
422
+    }
423
+
424
+    public Double getHeightMiddleError() 
425
+    {
426
+        return heightMiddleError;
427
+    }
428
+
429
+    public void setLevel(int level) 
430
+    {
431
+        this.level = level;
432
+    }
433
+
434
+    public int getLevel() 
435
+    {
436
+        return level;
437
+    }
438
+
439
+    public void setLatitudePosition(String latitudePosition) 
440
+    {
441
+        this.latitudePosition = latitudePosition;
442
+    }
443
+
444
+    public String getLatitudePosition() 
445
+    {
446
+        return latitudePosition;
447
+    }
448
+
449
+    public void setLongitudePosition(String longitudePosition) 
450
+    {
451
+        this.longitudePosition = longitudePosition;
452
+    }
453
+
454
+    public String getLongitudePosition() 
455
+    {
456
+        return longitudePosition;
457
+    }
458
+    
459
+    public void setProjectionHeight(Double projectionHeight) 
460
+    {
461
+        this.projectionHeight = projectionHeight;
462
+    }
463
+
464
+    public Double getProjectionHeight() 
465
+    {
466
+        return projectionHeight;
467
+    }
468
+
469
+    
470
+    @Override
471
+    public String toString() {
472
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
473
+            .append("id", getId())
474
+            .append("startPointNo", getStartPointNo())
475
+            .append("endPointNo", getEndPointNo())
476
+            .append("stationCount", getStationCount())
477
+            .append("distance", getDistance())
478
+            .append("heightDifference", getHeightDifference())
479
+            .append("scaleTrueLength", getScaleTrueLength())
480
+            .append("averageDistance", getAverageDistance())
481
+            .append("scaleCorrectedHeightDiff", getScaleCorrectedHeightDiff())
482
+            .append("averageScaleCorrectedHeightDiff", getAverageScaleCorrectedHeightDiff())
483
+            .append("roundTripDifference", getRoundTripDifference())
484
+            .append("tolerance", getTolerance())
485
+            .append("precisionStatistics", getPrecisionStatistics())
486
+            .append("qualityScore", getQualityScore())
487
+            .append("pendingPoint", getPendingPoint())
488
+            .append("coordinateX", getCoordinateX())
489
+            .append("coordinateY", getCoordinateY())
490
+            .append("heightH", getHeightH())
491
+            .append("coordinateSystem", getCoordinateSystem())
492
+            .append("zoneNo", getZoneNo())
493
+            .append("bandWidth", getBandWidth())
494
+            .append("geodeticLongitude", getGeodeticLongitude())
495
+            .append("geodeticLatitude", getGeodeticLatitude())
496
+            .append("pointCorrection", getPointCorrection())
497
+            .append("correctedHeightDifference", getCorrectedHeightDifference())
498
+            .append("elevation", getElevation())
499
+            .append("distanceFromStart", getDistanceFromStart())
500
+            .append("heightMiddleError", getHeightMiddleError())
501
+            .append("level", getLevel())
502
+            .append("latitudePosition", getLatitudePosition())
503
+            .append("longitudePosition", getLongitudePosition())
504
+            .append("projectionHeight", getProjectionHeight())
505
+            .append("createTime", getCreateTime())
506
+            .append("createBy", getCreateBy())
507
+            .append("updateTime", getUpdateTime())
508
+            .append("updateBy", getUpdateBy())
509
+            .toString();
510
+    }
511
+}

+ 13
- 0
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/domain/CmcSpatialToGeodetic.java Просмотреть файл

@@ -66,6 +66,9 @@ public class CmcSpatialToGeodetic extends BaseEntity
66 66
     @Excel(name = "投影面高程", cellType = ColumnType.NUMERIC)
67 67
     private double projectionHeight;
68 68
 
69
+    /** 输出角度格式:degree(度) / dms(度分秒) */
70
+    private String outputFormat;
71
+
69 72
     public void setId(Long id) 
70 73
     {
71 74
         this.id = id;
@@ -203,6 +206,16 @@ public class CmcSpatialToGeodetic extends BaseEntity
203 206
     {
204 207
         return projectionHeight;
205 208
     }
209
+    
210
+    public void setOutputFormat(String outputFormat) 
211
+    {
212
+        this.outputFormat = outputFormat;
213
+    }
214
+
215
+    public String getOutputFormat() 
216
+    {
217
+        return outputFormat;
218
+    }
206 219
 
207 220
     @Override
208 221
     public String toString() {

+ 16
- 3
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/domain/CmcUTMNegative.java Просмотреть файл

@@ -40,12 +40,15 @@ public class CmcUTMNegative extends BaseEntity
40 40
 
41 41
     /** 带号 */
42 42
     @Excel(name = "带号", cellType = ColumnType.NUMERIC)
43
-    private Integer band;
43
+    private Double band;
44 44
 
45 45
     /** 投影面高程 */
46 46
     @Excel(name = "投影面高程", cellType = ColumnType.NUMERIC)
47 47
     private double projectionHeight;
48 48
 
49
+    /** 输出格式:degree(度) / dms(度分秒) */
50
+    private String outputFormat;
51
+
49 52
     /** 大地经度 */
50 53
     @Excel(name = "大地经度" , cellType = ColumnType.NUMERIC,numberFormat = "0.000000000")
51 54
     private Double longitude;
@@ -109,12 +112,12 @@ public class CmcUTMNegative extends BaseEntity
109 112
         return utmY;
110 113
     }
111 114
     
112
-    public void setBand(Integer band) 
115
+    public void setBand(Double band) 
113 116
     {
114 117
         this.band = band;
115 118
     }
116 119
 
117
-    public Integer getBand() 
120
+    public Double getBand() 
118 121
     {
119 122
         return band;
120 123
     }
@@ -129,6 +132,16 @@ public class CmcUTMNegative extends BaseEntity
129 132
         return projectionHeight;
130 133
     }
131 134
     
135
+    public void setOutputFormat(String outputFormat) 
136
+    {
137
+        this.outputFormat = outputFormat;
138
+    }
139
+
140
+    public String getOutputFormat() 
141
+    {
142
+        return outputFormat;
143
+    }
144
+    
132 145
     public void setLongitude(Double longitude) 
133 146
     {
134 147
         if (longitude != null) {

+ 18
- 3
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/domain/CmcUTMPositive.java Просмотреть файл

@@ -48,12 +48,15 @@ public class CmcUTMPositive extends BaseEntity
48 48
 
49 49
     /** 带号 */
50 50
     @Excel(name = "带号", cellType = ColumnType.NUMERIC)
51
-    private Integer band;
51
+    private Double band;
52 52
 
53 53
     /** 投影面高程 */
54 54
     @Excel(name = "投影面高程", cellType = ColumnType.NUMERIC)
55 55
     private double projectionHeight;
56 56
 
57
+    /** 角度格式:degree(度) / dms(度分秒) */
58
+    private String angleFormat;
59
+
57 60
     /** UTM坐标x */
58 61
     @Excel(name = "UTM坐标x", cellType = ColumnType.NUMERIC, numberFormat = "0.0000")
59 62
     private Double utmX;
@@ -143,12 +146,12 @@ public class CmcUTMPositive extends BaseEntity
143 146
         return latitudePosition;
144 147
     }
145 148
     
146
-    public void setBand(Integer band) 
149
+    public void setBand(Double band) 
147 150
     {
148 151
         this.band = band;
149 152
     }
150 153
 
151
-    public Integer getBand() 
154
+    public Double getBand() 
152 155
     {
153 156
         return band;
154 157
     }
@@ -163,6 +166,16 @@ public class CmcUTMPositive extends BaseEntity
163 166
         return projectionHeight;
164 167
     }
165 168
     
169
+    public void setAngleFormat(String angleFormat) 
170
+    {
171
+        this.angleFormat = angleFormat;
172
+    }
173
+
174
+    public String getAngleFormat() 
175
+    {
176
+        return angleFormat;
177
+    }
178
+    
166 179
     public void setUtmX(Double utmX) 
167 180
     {
168 181
         this.utmX = utmX;
@@ -213,6 +226,8 @@ public class CmcUTMPositive extends BaseEntity
213 226
             .append("utmX", getUtmX())
214 227
             .append("utmY", getUtmY())
215 228
             .append("meridianConvergence", getMeridianConvergence())
229
+            .append("projectionHeight", getProjectionHeight())
230
+            .append("angleFormat", getAngleFormat())
216 231
             .append("createTime", getCreateTime())
217 232
             .append("createBy", getCreateBy())
218 233
             .append("updateTime", getUpdateTime())

+ 48
- 0
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/ICmcNonparallelismCorrectionService.java Просмотреть файл

@@ -0,0 +1,48 @@
1
+package com.ruoyi.web.calculate.service;
2
+
3
+import java.util.List;
4
+import java.util.Map;
5
+
6
+import javax.servlet.http.HttpServletResponse;
7
+
8
+import org.springframework.web.multipart.MultipartFile;
9
+
10
+import com.ruoyi.common.core.domain.AjaxResult;
11
+import com.ruoyi.web.calculate.domain.CmcEleDifSideLandDir;
12
+import com.ruoyi.web.calculate.domain.CmcNonparallelismCorrection;
13
+
14
+/**
15
+ * 非平行差改正服务接口
16
+ * 
17
+ * @author qyx
18
+ * @date 2026-06-22
19
+ */
20
+public interface ICmcNonparallelismCorrectionService {
21
+
22
+    /**
23
+     * 导入Excel数据(支持多个工作表和列映射)
24
+     * 
25
+     * @param file           Excel文件
26
+     * @param sheetNames     工作表名称列表(可选,为空时读取所有工作表)
27
+     * @param columnMappings 列映射配置(JSON字符串)
28
+     * @return 导入结果
29
+     */
30
+    public AjaxResult importExcelData(MultipartFile file, List<String> sheetNames, String columnMappings);
31
+
32
+    /**
33
+     * 执行非平行差改正计算
34
+     * 
35
+     * @param cmcNonparallelismCorrection 非平行差改正参数
36
+     * @return 计算结果
37
+     */
38
+    public List<CmcNonparallelismCorrection> calculateNonparallelismCorrection(
39
+            List<CmcNonparallelismCorrection> dataList);
40
+
41
+    /**
42
+    * 获取Excel文件的所有工作表名称
43
+    * 
44
+    * @param file Excel文件
45
+    * @return 工作表名称列表
46
+    */
47
+    public List<String> getSheetNames(MultipartFile file);
48
+}

+ 22
- 11
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/impl/CmcGaussNegativeServiceImpl.java Просмотреть файл

@@ -232,19 +232,20 @@ public class CmcGaussNegativeServiceImpl implements ICmcGaussNegativeService {
232 232
     }
233 233
 
234 234
     /**
235
-     * 单条高斯
235
+     * 单条高斯
236 236
      */
237 237
     private CmcGaussNegative calculateGaussNegativeSingle(CmcGaussNegative cmcGaussNegative) {
238 238
         try {
239 239
             initEllipsoidParams(cmcGaussNegative.getCoordinateSystem());
240 240
             
241
-            double gaussX = cmcGaussNegative.getGaussX(); // 经度(度)
242
-            double gaussY = cmcGaussNegative.getGaussY(); // 经度(度)
243
-            String longitudePosition = cmcGaussNegative.getLongitudePosition(); // 经度位置(东/西)
244
-            String latitudePosition = cmcGaussNegative.getLatitudePosition(); // 纬度位置(北/南)
245
-            double projectionHeight = cmcGaussNegative.getProjectionHeight(); // 投影面高程
241
+            double gaussX = cmcGaussNegative.getGaussX();
242
+            double gaussY = cmcGaussNegative.getGaussY();
243
+            String longitudePosition = cmcGaussNegative.getLongitudePosition();
244
+            String latitudePosition = cmcGaussNegative.getLatitudePosition();
245
+            double projectionHeight = cmcGaussNegative.getProjectionHeight();
246
+            String outputFormat = cmcGaussNegative.getOutputFormat();
246 247
             String yStr = String.valueOf(Math.abs((long) gaussY));
247
-            int band = cmcGaussNegative.getBand();
248
+            double band = cmcGaussNegative.getBand();
248 249
             int bandwidth = cmcGaussNegative.getBandwidth();
249 250
 
250 251
             double x = latitudePosition.equals("S") ? 10000000 - gaussX : gaussX;
@@ -264,9 +265,19 @@ public class CmcGaussNegativeServiceImpl implements ICmcGaussNegativeService {
264 265
             //计算L
265 266
             double L = calculateL(bf, tf, etaf2, n, longitudePosition, bandwidth, band);
266 267
 
267
-            //大地经度和大地纬度
268
-            double longitude = convertDecimalDegrees(L);
269
-            double latitude = convertDecimalDegrees(B);
268
+            double longitude = L;
269
+            double latitude = B;
270
+            //大地经度和大地纬度(默认为度分秒格式)
271
+            if ("dms".equals(outputFormat)) {
272
+                longitude = convertDecimalDegrees(L);
273
+                latitude = convertDecimalDegrees(B);
274
+            }
275
+            
276
+            // 如果输出格式为度(degree),则将度分秒转换为十进制度
277
+            // if ("degree".equalsIgnoreCase(outputFormat)) {
278
+            //     longitude = convertDMSToDegree(longitude);
279
+            //     latitude = convertDMSToDegree(latitude);
280
+            // }
270 281
 
271 282
             cmcGaussNegative.setLongitude(longitude);
272 283
             cmcGaussNegative.setLatitude(latitude);
@@ -404,7 +415,7 @@ public class CmcGaussNegativeServiceImpl implements ICmcGaussNegativeService {
404 415
     }
405 416
 
406 417
     /**
407
-     * 将十进制度数数值转换为度分秒格式
418
+     * 将度分秒数值转换为十进制度数
408 419
      * 
409 420
      * @param decimalDegrees 十进制度数数值
410 421
      * @return 转换后的值

+ 39
- 6
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/impl/CmcGaussPositiveServiceImpl.java Просмотреть файл

@@ -243,11 +243,18 @@ public class CmcGaussPositiveServiceImpl implements ICmcGaussPositiveService
243 243
         try {
244 244
             initEllipsoidParams(cmcGaussPositive.getCoordinateSystem());
245 245
 
246
-            double longitude = cmcGaussPositive.getLongitude(); // 经度(度)
246
+            double longitude = cmcGaussPositive.getLongitude(); // 经度
247 247
             String longitudePosition = cmcGaussPositive.getLongitudePosition(); // 经度位置(东/西)
248 248
             String latitudePosition = cmcGaussPositive.getLatitudePosition(); // 纬度位置(北/南)
249
-            double latitude = cmcGaussPositive.getLatitude(); // 纬度(度)
250
-            Integer band = cmcGaussPositive.getBand(); // 带号
249
+            double latitude = cmcGaussPositive.getLatitude(); // 纬度
250
+            String angleFormat = cmcGaussPositive.getAngleFormat(); // 角度格式
251
+            
252
+            // 如果输入格式为度(degree),先转换为度分秒格式
253
+            // if ("degree".equalsIgnoreCase(angleFormat)) {
254
+            //     longitude = convertDegreeToDMS(longitude);
255
+            //     latitude = convertDegreeToDMS(latitude);
256
+            // }
257
+            double band = cmcGaussPositive.getBand(); // 带号
251 258
             int bandwidth = cmcGaussPositive.getBandwidth(); // 带宽
252 259
             double projectionHeight = cmcGaussPositive.getProjectionHeight(); // 投影面高程
253 260
 
@@ -258,14 +265,18 @@ public class CmcGaussPositiveServiceImpl implements ICmcGaussPositiveService
258 265
             } else { // 3度带
259 266
                 centralMeridian = band * 3;
260 267
             }
268
+            double B = latitude * Math.PI / 180;
269
+            double L = longitude;
261 270
             // 转换为弧度
262
-            double B = convertDecimalDegrees(latitude) * Math.PI / 180;
263
-            double L = convertDecimalDegrees(longitude);
271
+            if ("dms".equalsIgnoreCase(angleFormat)) {
272
+                B = convertDecimalDegrees(latitude) * Math.PI / 180;
273
+                L = convertDecimalDegrees(longitude);
274
+            }
264 275
             // double L0 = Math.toRadians(centralMeridian);
265 276
            
266 277
             // 计算经差
267 278
             double l = (centralMeridian - L) * Math.PI / 180;
268
-            // 处理西经情况
279
+            // 处理东经度情况
269 280
             if ("东".equals(longitudePosition) || "E".equalsIgnoreCase(longitudePosition)) {
270 281
                 l = (L - centralMeridian) * Math.PI / 180;
271 282
             }
@@ -399,6 +410,28 @@ public class CmcGaussPositiveServiceImpl implements ICmcGaussPositiveService
399 410
         return X;
400 411
     }
401 412
     
413
+    /**
414
+     * 将十进制度数转换为度分秒格式数值(DD.MMSSssss)
415
+     * 与 calculateDegreeToDMSSingle 方法逻辑相同
416
+     * 
417
+     * @param decimalDegrees 十进制度数(如 103.373428195)
418
+     * @return 度分秒格式数值(如 103.22240038)
419
+     */
420
+    private double convertDegreeToDMS(double decimalDegrees) {
421
+        // 1. 提取度
422
+        double degrees = Math.floor(decimalDegrees + 1.0E-13);
423
+        
424
+        // 2. 提取分
425
+        double minutesRaw = 60 * (decimalDegrees - degrees);
426
+        double minutes = Math.floor(minutesRaw + 1.0E-13) / 100;
427
+        
428
+        // 3. 提取秒
429
+        double secondsRaw = 60 * (60 * decimalDegrees - Math.floor(60 * decimalDegrees + 1.0E-13)) + 1.0E-13;
430
+        double seconds = secondsRaw / 10000;
431
+        
432
+        return degrees + minutes + seconds;
433
+    }
434
+    
402 435
     /**
403 436
      * 将十进制度数转换为特定格式(
404 437
      * @param decimalDegrees 十进制度数

+ 11
- 5
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/impl/CmcGeodeticToSpatialServiceImpl.java Просмотреть файл

@@ -283,17 +283,23 @@ public class CmcGeodeticToSpatialServiceImpl implements ICmcGeodeticToSpatialSer
283 283
         String latitudePosition = cmcGeodeticToSpatial.getLatitudePosition(); // 纬度位置 N/S
284 284
         double projectionHeight = cmcGeodeticToSpatial.getProjectionHeight(); // 投影高
285 285
         double height = cmcGeodeticToSpatial.getHeight(); // 大地高
286
+        String angleFormat = cmcGeodeticToSpatial.getAngleFormat(); // 角度格式
286 287
         double j = 1.5e-12;
287 288
 
288 289
         // 初始化椭球参数
289 290
         initEllipsoidParams(coordinateSystem);
290 291
 
291 292
         double a = A + projectionHeight;
292
-        // 将角度转换为弧度
293
-        double B = latitudePosition.equals("N") ? calculateRadianValue(latitude, j)
294
-                : -calculateRadianValue(latitude, j); // 纬度弧度
295
-        double L = longitudePosition.equals("E") ? calculateRadianValue(longitude, j)
296
-                : -calculateRadianValue(longitude, j);// 经度弧度
293
+        double B = latitude / 180.0 * Math.PI;
294
+        double L = longitude / 180.0 * Math.PI;
295
+        if("dms".equalsIgnoreCase(angleFormat)){
296
+            // 将角度转换为弧度
297
+            B = latitudePosition.equals("N") ? calculateRadianValue(latitude, j)
298
+                    : -calculateRadianValue(latitude, j); // 纬度弧度
299
+            L = longitudePosition.equals("E") ? calculateRadianValue(longitude, j)
300
+                    : -calculateRadianValue(longitude, j);// 经度弧度
301
+        }
302
+        
297 303
 
298 304
         // 计算卯酉圈曲率半径 N = a / sqrt(1 - e² * sin²(B))
299 305
         double sinB = Math.sin(B);

+ 785
- 0
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/impl/CmcNonparallelismCorrectionServiceImpl.java Просмотреть файл

@@ -0,0 +1,785 @@
1
+package com.ruoyi.web.calculate.service.impl;
2
+
3
+import java.io.InputStream;
4
+import java.math.BigDecimal;
5
+import java.math.RoundingMode;
6
+import java.util.ArrayList;
7
+import java.util.HashMap;
8
+import java.util.List;
9
+import java.util.Map;
10
+
11
+import javax.servlet.http.HttpServletResponse;
12
+
13
+import org.springframework.beans.factory.annotation.Autowired;
14
+import org.springframework.stereotype.Service;
15
+import org.springframework.transaction.annotation.Transactional;
16
+import org.springframework.web.multipart.MultipartFile;
17
+
18
+import com.fasterxml.jackson.core.type.TypeReference;
19
+import com.fasterxml.jackson.databind.ObjectMapper;
20
+import com.ruoyi.common.core.domain.AjaxResult;
21
+import com.ruoyi.common.utils.poi.ExcelUtil;
22
+import com.ruoyi.web.calculate.domain.CmcNonparallelismCorrection;
23
+import com.ruoyi.web.calculate.service.ICmcNonparallelismCorrectionService;
24
+
25
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
26
+import org.apache.poi.ss.usermodel.Cell;
27
+import org.apache.poi.ss.usermodel.CellType;
28
+import org.apache.poi.ss.usermodel.DateUtil;
29
+import org.apache.poi.ss.usermodel.Row;
30
+import org.apache.poi.ss.usermodel.Sheet;
31
+import org.apache.poi.ss.usermodel.Workbook;
32
+import org.apache.poi.ss.usermodel.WorkbookFactory;
33
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
34
+
35
+/**
36
+ * 非平行差改正服务实现
37
+ * 
38
+ * @author qyx
39
+ * @date 2026-06-22
40
+ */
41
+@Service
42
+public class CmcNonparallelismCorrectionServiceImpl implements ICmcNonparallelismCorrectionService {
43
+
44
+    // 扁率直接计算精度不够,在后面的椭球参数选择中用BigDecimal计算,下面的F是分母
45
+    private static final double A_WGS84 = 6378137.0;
46
+    private static final String F_WGS84 = "298.257223563";
47
+
48
+    private static final double A_CGCS2000 = 6378137.0;
49
+    private static final String F_CGCS2000 = "298.257222101";
50
+
51
+    private static final double A_BJ54 = 6378245.0;
52
+    private static final String F_BJ54 = "298.3";
53
+
54
+    private static final double A_XA80 = 6378140.0;
55
+    private static final String F_XA80 = "298.257";
56
+
57
+    private static double A;
58
+    private static double F;
59
+    private static double E2;
60
+
61
+    
62
+    /**
63
+     * 导入Excel数据(支持多个工作表和列映射)
64
+     * 重构后:返回所有工作表信息,由前端选择工作表和配置字段映射
65
+     */
66
+    @Override
67
+    @Transactional(rollbackFor = Exception.class)
68
+    public AjaxResult importExcelData(MultipartFile file, List<String> sheetNames, String columnMappingsJson) {
69
+        try {
70
+            // 获取所有工作表名称
71
+            List<String> allSheetNames = getSheetNames(file);
72
+            
73
+            // 存储每个工作表的信息
74
+            List<Map<String, Object>> sheetInfoList = new ArrayList<>();
75
+            
76
+            // 读取每个工作表的表头和原始数据
77
+            for (String sheetName : allSheetNames) {
78
+                List<String> headers = readSheetHeaders(file, sheetName);
79
+                List<Map<String, Object>> rawData = readRawSheetDataAsMap(file, sheetName, headers);
80
+                
81
+                Map<String, Object> sheetInfo = new HashMap<>();
82
+                sheetInfo.put("sheetName", sheetName);
83
+                sheetInfo.put("headers", headers);
84
+                sheetInfo.put("rawData", rawData);
85
+                sheetInfoList.add(sheetInfo);
86
+            }
87
+
88
+            // 构建返回结果(参考gausspositive格式,但支持多sheet)
89
+            Map<String, Object> result = new HashMap<>();
90
+            result.put("sheetNames", allSheetNames);
91
+            result.put("sheetInfo", sheetInfoList);
92
+
93
+            String message = String.format("导入成功!共%d个工作表", allSheetNames.size());
94
+            return AjaxResult.success(message, result);
95
+
96
+        } catch (Exception e) {
97
+            e.printStackTrace();
98
+            return AjaxResult.error("导入失败:" + e.getMessage());
99
+        }
100
+    }
101
+    
102
+    /**
103
+     * 读取工作表的表头信息
104
+     * 
105
+     * @param file Excel文件
106
+     * @param sheetName 工作表名称
107
+     * @return 表头列表
108
+     */
109
+    private List<String> readSheetHeaders(MultipartFile file, String sheetName) {
110
+        List<String> headers = new ArrayList<>();
111
+        
112
+        try (InputStream inputStream = file.getInputStream();
113
+             Workbook workbook = createWorkbook(inputStream, file.getOriginalFilename())) {
114
+            // 查找指定名称的工作表
115
+            Sheet sheet = workbook.getSheet(sheetName);
116
+            
117
+            if (sheet == null) {
118
+                // 如果按名称找不到,尝试按索引查找
119
+                try {
120
+                    int sheetIndex = Integer.parseInt(sheetName);
121
+                    sheet = workbook.getSheetAt(sheetIndex);
122
+                } catch (NumberFormatException e) {
123
+                    return headers;
124
+                }
125
+            }
126
+            
127
+            if (sheet == null) {
128
+                return headers;
129
+            }
130
+            
131
+            // 读取第一行作为表头
132
+            org.apache.poi.ss.usermodel.Row headerRow = sheet.getRow(0);
133
+            if (headerRow != null) {
134
+                int lastCellNum = headerRow.getLastCellNum();
135
+                for (int i = 0; i < lastCellNum; i++) {
136
+                    String header = getCellStringValue(headerRow.getCell(i));
137
+                    // 过滤掉null、空字符串和"null"字符串的表头,避免生成null键导致JSON序列化失败
138
+                    if (header != null && !header.trim().isEmpty() && !"null".equalsIgnoreCase(header.trim())) {
139
+                        headers.add(header);
140
+                    }
141
+                }
142
+            }
143
+            
144
+        } catch (Exception e) {
145
+            e.printStackTrace();
146
+        }
147
+        
148
+        return headers;
149
+    }
150
+    
151
+    /**
152
+     * 读取工作表的原始数据(从第二行开始),转换为Map格式
153
+     * 
154
+     * @param file Excel文件
155
+     * @param sheetName 工作表名称
156
+     * @param headers 表头列表
157
+     * @return 原始数据列表(Map格式)
158
+     */
159
+    private List<Map<String, Object>> readRawSheetDataAsMap(MultipartFile file, String sheetName, List<String> headers) {
160
+        List<Map<String, Object>> rawData = new ArrayList<>();
161
+        
162
+        try (InputStream inputStream = file.getInputStream();
163
+             Workbook workbook = createWorkbook(inputStream, file.getOriginalFilename())) {
164
+            // 查找指定名称的工作表
165
+            Sheet sheet = workbook.getSheet(sheetName);
166
+            
167
+            if (sheet == null) {
168
+                try {
169
+                    int sheetIndex = Integer.parseInt(sheetName);
170
+                    sheet = workbook.getSheetAt(sheetIndex);
171
+                } catch (NumberFormatException e) {
172
+                    return rawData;
173
+                }
174
+            }
175
+            
176
+            if (sheet == null) {
177
+                return rawData;
178
+            }
179
+            
180
+            // 从第二行开始读取数据
181
+            int lastRowNum = sheet.getLastRowNum();
182
+            for (int i = 1; i <= lastRowNum; i++) {
183
+                org.apache.poi.ss.usermodel.Row row = sheet.getRow(i);
184
+                if (row == null) continue;
185
+                
186
+                Map<String, Object> rowData = new HashMap<>();
187
+                for (int j = 0; j < headers.size(); j++) {
188
+                    rowData.put(headers.get(j), getCellStringValue(row.getCell(j)));
189
+                }
190
+                
191
+                // 跳过空行
192
+                boolean hasData = false;
193
+                for (Object obj : rowData.values()) {
194
+                    if (obj != null && !"".equals(obj.toString().trim())) {
195
+                        hasData = true;
196
+                        break;
197
+                    }
198
+                }
199
+                if (hasData) {
200
+                    rawData.add(rowData);
201
+                }
202
+            }
203
+            
204
+        } catch (Exception e) {
205
+            e.printStackTrace();
206
+        }
207
+        
208
+        return rawData;
209
+    }
210
+    
211
+    /**
212
+     * 从指定工作表读取Excel数据
213
+     * 
214
+     * @param file Excel文件
215
+     * @param sheetName 工作表名称
216
+     * @return 数据列表
217
+     */
218
+    private List<CmcNonparallelismCorrection> importExcelFromSheet(MultipartFile file, String sheetName) {
219
+        return importExcelFromSheet(file, sheetName, null);
220
+    }
221
+    
222
+    /**
223
+     * 从指定工作表读取Excel数据(支持列映射)
224
+     * 
225
+     * @param file Excel文件
226
+     * @param sheetName 工作表名称
227
+     * @param columnMapping 列映射配置(字段名 -> 列索引),为空则使用默认映射
228
+     * @return 数据列表
229
+     */
230
+    private List<CmcNonparallelismCorrection> importExcelFromSheet(MultipartFile file, String sheetName, Map<String, Integer> columnMapping) {
231
+        List<CmcNonparallelismCorrection> dataList = new ArrayList<>();
232
+        
233
+        try (InputStream inputStream = file.getInputStream();
234
+             Workbook workbook = createWorkbook(inputStream, file.getOriginalFilename())) {
235
+            // 查找指定名称的工作表
236
+            Sheet sheet = workbook.getSheet(sheetName);
237
+            
238
+            if (sheet == null) {
239
+                // 如果按名称找不到,尝试按索引查找
240
+                try {
241
+                    int sheetIndex = Integer.parseInt(sheetName);
242
+                    sheet = workbook.getSheetAt(sheetIndex);
243
+                } catch (NumberFormatException e) {
244
+                    // 不是数字索引,返回空列表
245
+                    return dataList;
246
+                }
247
+            }
248
+            
249
+            if (sheet == null) {
250
+                return dataList;
251
+            }
252
+            
253
+            // 直接使用POI解析Sheet数据
254
+            int lastRowNum = sheet.getLastRowNum();
255
+            // 从第二行开始读取(跳过表头)
256
+            for (int i = 1; i <= lastRowNum; i++) {
257
+                org.apache.poi.ss.usermodel.Row row = sheet.getRow(i);
258
+                if (row == null) {
259
+                    continue;
260
+                }
261
+                
262
+                CmcNonparallelismCorrection item = new CmcNonparallelismCorrection();
263
+                
264
+                if (columnMapping != null && !columnMapping.isEmpty()) {
265
+                    // 使用自定义列映射
266
+                    // 测段高差计算字段
267
+                    int colIndex = columnMapping.getOrDefault("startPointNo", -1);
268
+                    if (colIndex >= 0) {
269
+                        item.setStartPointNo(getCellStringValue(row.getCell(colIndex)));
270
+                    }
271
+                    
272
+                    colIndex = columnMapping.getOrDefault("endPointNo", -1);
273
+                    if (colIndex >= 0) {
274
+                        item.setEndPointNo(getCellStringValue(row.getCell(colIndex)));
275
+                    }
276
+                    
277
+                    colIndex = columnMapping.getOrDefault("distance", -1);
278
+                    if (colIndex >= 0) {
279
+                        item.setDistance(getCellDoubleValue(row.getCell(colIndex)));
280
+                    }
281
+                    
282
+                    colIndex = columnMapping.getOrDefault("heightDifference", -1);
283
+                    if (colIndex >= 0) {
284
+                        item.setHeightDifference(getCellDoubleValue(row.getCell(colIndex)));
285
+                    }
286
+                    
287
+                    colIndex = columnMapping.getOrDefault("scaleTrueLength", -1);
288
+                    if (colIndex >= 0) {
289
+                        item.setScaleTrueLength(getCellDoubleValue(row.getCell(colIndex)));
290
+                    }
291
+                    
292
+                    colIndex = columnMapping.getOrDefault("level", -1);
293
+                    if (colIndex >= 0) {
294
+                        Integer levelValue = getCellIntegerValue(row.getCell(colIndex));
295
+                        item.setLevel(levelValue != null ? levelValue : 0);
296
+                    }
297
+                    
298
+                    // 不平行改正计算字段
299
+                    colIndex = columnMapping.getOrDefault("pendingPoint", -1);
300
+                    if (colIndex >= 0) {
301
+                        item.setPendingPoint(getCellStringValue(row.getCell(colIndex)));
302
+                    }
303
+                    
304
+                    colIndex = columnMapping.getOrDefault("coordinateX", -1);
305
+                    if (colIndex >= 0) {
306
+                        item.setCoordinateX(getCellDoubleValue(row.getCell(colIndex)));
307
+                    }
308
+                    
309
+                    colIndex = columnMapping.getOrDefault("coordinateY", -1);
310
+                    if (colIndex >= 0) {
311
+                        item.setCoordinateY(getCellDoubleValue(row.getCell(colIndex)));
312
+                    }
313
+                    
314
+                    colIndex = columnMapping.getOrDefault("heightH", -1);
315
+                    if (colIndex >= 0) {
316
+                        item.setHeightH(getCellDoubleValue(row.getCell(colIndex)));
317
+                    }
318
+                    
319
+                    colIndex = columnMapping.getOrDefault("coordinateSystem", -1);
320
+                    if (colIndex >= 0) {
321
+                        item.setCoordinateSystem(getCellStringValue(row.getCell(colIndex)));
322
+                    }
323
+                    
324
+                    colIndex = columnMapping.getOrDefault("zoneNo", -1);
325
+                    if (colIndex >= 0) {
326
+                        item.setZoneNo(getCellDoubleValue(row.getCell(colIndex)));
327
+                    }
328
+                    
329
+                    colIndex = columnMapping.getOrDefault("bandWidth", -1);
330
+                    if (colIndex >= 0) {
331
+                        item.setBandWidth(getCellDoubleValue(row.getCell(colIndex)));
332
+                    }
333
+                    
334
+                    colIndex = columnMapping.getOrDefault("latitudePosition", -1);
335
+                    if (colIndex >= 0) {
336
+                        item.setLatitudePosition(getCellStringValue(row.getCell(colIndex)));
337
+                    }
338
+                    
339
+                    colIndex = columnMapping.getOrDefault("longitudePosition", -1);
340
+                    if (colIndex >= 0) {
341
+                        item.setLongitudePosition(getCellStringValue(row.getCell(colIndex)));
342
+                    }
343
+                    
344
+                    colIndex = columnMapping.getOrDefault("projectionHeight", -1);
345
+                    if (colIndex >= 0) {
346
+                        item.setProjectionHeight(getCellDoubleValue(row.getCell(colIndex)));
347
+                    }
348
+                    
349
+                } else {
350
+                    // 使用默认列映射
351
+                    // 测段高差计算字段(前7列)
352
+                    item.setStartPointNo(getCellStringValue(row.getCell(0)));
353
+                    item.setEndPointNo(getCellStringValue(row.getCell(1)));
354
+                    item.setDistance(getCellDoubleValue(row.getCell(2)));
355
+                    item.setHeightDifference(getCellDoubleValue(row.getCell(3)));
356
+                    item.setScaleTrueLength(getCellDoubleValue(row.getCell(4)));
357
+                    Integer levelValue = getCellIntegerValue(row.getCell(5));
358
+                    item.setLevel(levelValue != null ? levelValue : 0);
359
+                    // 不平行改正计算字段(后续列)
360
+                    item.setPendingPoint(getCellStringValue(row.getCell(6)));
361
+                    item.setCoordinateX(getCellDoubleValue(row.getCell(7)));
362
+                    item.setCoordinateY(getCellDoubleValue(row.getCell(8)));
363
+                    item.setHeightH(getCellDoubleValue(row.getCell(9)));
364
+                    item.setCoordinateSystem(getCellStringValue(row.getCell(10)));
365
+                    item.setZoneNo(getCellDoubleValue(row.getCell(11)));
366
+                    item.setBandWidth(getCellDoubleValue(row.getCell(12)));
367
+                    item.setLatitudePosition(getCellStringValue(row.getCell(13)));
368
+                    item.setLongitudePosition(getCellStringValue(row.getCell(14)));
369
+                    item.setProjectionHeight(getCellDoubleValue(row.getCell(15)));
370
+                }
371
+                
372
+                dataList.add(item);
373
+            }
374
+            
375
+        } catch (Exception e) {
376
+            e.printStackTrace();
377
+        }
378
+        
379
+        return dataList;
380
+    }
381
+    
382
+    /**
383
+     * 获取单元格的字符串值
384
+     */
385
+    private String getCellStringValue(org.apache.poi.ss.usermodel.Cell cell) {
386
+        if (cell == null) {
387
+            return null;
388
+        }
389
+        switch (cell.getCellType()) {
390
+            case STRING:
391
+                return cell.getStringCellValue();
392
+            case NUMERIC:
393
+                // 数字类型转字符串,避免科学计数法
394
+                double numValue = cell.getNumericCellValue();
395
+                if (numValue == Math.floor(numValue)) {
396
+                    return String.valueOf((long) numValue);
397
+                }
398
+                return String.valueOf(numValue);
399
+            case BOOLEAN:
400
+                return String.valueOf(cell.getBooleanCellValue());
401
+            case FORMULA:
402
+                try {
403
+                    return cell.getStringCellValue();
404
+                } catch (Exception e) {
405
+                    return String.valueOf(cell.getNumericCellValue());
406
+                }
407
+            default:
408
+                return null;
409
+        }
410
+    }
411
+    
412
+    /**
413
+     * 获取单元格的Double值
414
+     */
415
+    private Double getCellDoubleValue(org.apache.poi.ss.usermodel.Cell cell) {
416
+        if (cell == null) {
417
+            return null;
418
+        }
419
+        switch (cell.getCellType()) {
420
+            case NUMERIC:
421
+                return cell.getNumericCellValue();
422
+            case STRING:
423
+                try {
424
+                    return Double.parseDouble(cell.getStringCellValue().trim());
425
+                } catch (NumberFormatException e) {
426
+                    return null;
427
+                }
428
+            default:
429
+                return null;
430
+        }
431
+    }
432
+    
433
+    /**
434
+     * 获取单元格的Integer值
435
+     */
436
+    private Integer getCellIntegerValue(org.apache.poi.ss.usermodel.Cell cell) {
437
+        if (cell == null) {
438
+            return null;
439
+        }
440
+        switch (cell.getCellType()) {
441
+            case NUMERIC:
442
+                return (int) cell.getNumericCellValue();
443
+            case STRING:
444
+                try {
445
+                    return Integer.parseInt(cell.getStringCellValue().trim());
446
+                } catch (NumberFormatException e) {
447
+                    return null;
448
+                }
449
+            default:
450
+                return null;
451
+        }
452
+    }
453
+
454
+    /**
455
+     * 根据文件类型创建Workbook
456
+     */
457
+    private Workbook createWorkbook(InputStream inputStream, String fileName) throws Exception {
458
+        if (fileName != null && fileName.endsWith(".xlsx")) {
459
+            return new XSSFWorkbook(inputStream);
460
+        } else {
461
+            return new HSSFWorkbook(inputStream);
462
+        }
463
+    }
464
+
465
+    /**
466
+     * 获取Excel文件的所有工作表名称
467
+     * 
468
+     * @param file Excel文件
469
+     * @return 工作表名称列表
470
+     */
471
+    @Override
472
+    public List<String> getSheetNames(MultipartFile file) {
473
+        List<String> sheetNames = new ArrayList<>();
474
+        
475
+        try (InputStream inputStream = file.getInputStream();
476
+             Workbook workbook = createWorkbook(inputStream, file.getOriginalFilename())) {
477
+            int numberOfSheets = workbook.getNumberOfSheets();
478
+            for (int i = 0; i < numberOfSheets; i++) {
479
+                sheetNames.add(workbook.getSheetName(i));
480
+            }
481
+        } catch (Exception e) {
482
+            e.printStackTrace();
483
+        }
484
+        
485
+        return sheetNames;
486
+    }
487
+
488
+    /**
489
+     * 执行非平行差改正计算
490
+     */
491
+    @Override
492
+    public List<CmcNonparallelismCorrection> calculateNonparallelismCorrection(
493
+            List<CmcNonparallelismCorrection> dataList) {
494
+        List<CmcNonparallelismCorrection> resultList = new ArrayList<>();
495
+        initEllipsoidParams(dataList.get(0).getCoordinateSystem());
496
+        int level = dataList.get(0).getLevel();
497
+        double distanceFromStart = 0;
498
+
499
+        for (int i = 0; i < dataList.size()-1; i++) {
500
+            CmcNonparallelismCorrection item1 = dataList.get(i);
501
+            CmcNonparallelismCorrection item2 = dataList.get(i + 1);
502
+            double dist1 = item1.getDistance();
503
+            double dist2 = item2.getDistance();
504
+            double heightdiff1 = item1.getHeightDifference();
505
+            double heightdiff2 = item2.getHeightDifference();
506
+            double truelen1 = item1.getScaleTrueLength();
507
+            double truelen2 = item2.getScaleTrueLength();
508
+            double Z1 = item1.getHeightH();
509
+            double Z2 = item2.getHeightH();
510
+            double band1 = item1.getZoneNo();
511
+            double height = item1.getHeightH();
512
+
513
+            double averageDistance = (dist1 + dist2) / 2/1000;
514
+            double scale1 = heightdiff1 * truelen1;
515
+            double scale2 = heightdiff2 * truelen2;
516
+            double averageScale = (scale1 - scale2) / 2;
517
+            double roundTripDifference = (scale1 + scale2) * 1000;
518
+            double tolerance = level == 2 ? 4 * Math.sqrt(averageDistance)
519
+                    : level == 3 ? 12 * Math.sqrt(averageDistance) : 20 * Math.sqrt(averageDistance);
520
+            double precisionStatistics = roundTripDifference * roundTripDifference / 4 / averageDistance;
521
+            double qualityScore = calculateQualityScore(roundTripDifference, tolerance);
522
+
523
+            // 计算正常重力值
524
+            double gamma1 = calculategamma(item1);
525
+            double gamma2 = calculategamma(item2);
526
+            double gammam = (gamma1 + gamma2) / 2 - 0.1543 * (Z1 + Z2) / 2;
527
+            double pointCorrection = -(gamma2 - gamma1) * (Z1 + Z2) / 2 / gammam;
528
+            double correctedHeightDifference = averageScale + pointCorrection;
529
+            double elevation = height + correctedHeightDifference;
530
+
531
+            double distanceFromStart1 = i == 0 ? 0 : dataList.get(i - 1).getDistanceFromStart();
532
+            distanceFromStart += averageDistance;
533
+            double distanceFromStart2 = distanceFromStart;
534
+
535
+            double heightMiddleError1 = level == 2 ? Math.sqrt(distanceFromStart1)
536
+                    : level == 3 ? Math.sqrt(distanceFromStart1) * 3 : Math.sqrt(distanceFromStart1) * 5;
537
+            double heightMiddleError2 = level == 2 ? Math.sqrt(distanceFromStart2)
538
+                    : level == 3 ? Math.sqrt(distanceFromStart2) * 3 : Math.sqrt(distanceFromStart2) * 5;
539
+            item1.setAverageDistance(averageDistance);
540
+            item1.setScaleCorrectedHeightDiff(heightMiddleError1);
541
+            item2.setScaleCorrectedHeightDiff(heightMiddleError2);
542
+            item1.setAverageScaleCorrectedHeightDiff(averageScale);
543
+            item1.setRoundTripDifference(roundTripDifference);
544
+            item1.setTolerance(tolerance);
545
+            item1.setPrecisionStatistics(precisionStatistics);
546
+            item1.setQualityScore(qualityScore);
547
+            item1.setPointCorrection(pointCorrection);
548
+            item1.setCorrectedHeightDifference(correctedHeightDifference);
549
+            item1.setElevation(height);
550
+            item2.setElevation(elevation);
551
+            item1.setDistanceFromStart(distanceFromStart1);
552
+            item2.setDistanceFromStart(distanceFromStart2);
553
+            item1.setHeightMiddleError(heightMiddleError1);
554
+            item2.setHeightMiddleError(heightMiddleError2);
555
+            resultList.add(item1);
556
+            resultList.add(item2);
557
+            i++;
558
+        }
559
+
560
+        return resultList;
561
+    }
562
+
563
+    // 选择椭球体参数
564
+    private void initEllipsoidParams(String coordinateSystem) {
565
+        String F_str;
566
+        if ("CGCS2000".equalsIgnoreCase(coordinateSystem) || "国家2000".equalsIgnoreCase(coordinateSystem)
567
+                || "2000".equalsIgnoreCase(coordinateSystem)) {
568
+            A = A_CGCS2000;
569
+            F_str = F_CGCS2000;
570
+        } else if ("1954".equalsIgnoreCase(coordinateSystem) || "北京54".equalsIgnoreCase(coordinateSystem)
571
+                || "Beijing54".equalsIgnoreCase(coordinateSystem)
572
+                || "54".equalsIgnoreCase(coordinateSystem)) {
573
+            A = A_BJ54;
574
+            F_str = F_BJ54;
575
+        } else if ("1980".equalsIgnoreCase(coordinateSystem) || "西安80".equalsIgnoreCase(coordinateSystem)
576
+                || "Xian80".equalsIgnoreCase(coordinateSystem)
577
+                || "80".equalsIgnoreCase(coordinateSystem)) {
578
+            A = A_XA80;
579
+            F_str = F_XA80;
580
+        } else {
581
+            A = A_WGS84;
582
+            F_str = F_WGS84;
583
+        }
584
+        BigDecimal one = BigDecimal.ONE;
585
+        BigDecimal divisor = new BigDecimal(F_str);
586
+        BigDecimal db_F = one.divide(divisor, 20, RoundingMode.HALF_UP);
587
+
588
+        // 计算 2 * F
589
+        BigDecimal two = new BigDecimal("2");
590
+        BigDecimal twoF = two.multiply(db_F);
591
+
592
+        // 计算 F * F
593
+        BigDecimal F_squared = db_F.multiply(db_F);
594
+
595
+        // 计算 e2 = 2*F - F*F
596
+        BigDecimal e2 = twoF.subtract(F_squared);
597
+        E2 = e2.doubleValue();
598
+        F = db_F.doubleValue();
599
+    }
600
+
601
+    /**
602
+     * 根据往返较差和限差计算质量评分
603
+     * 
604
+     * @param diff  往返较差
605
+     * @param limit 限差
606
+     * @return 质量评分(0-100分),或 -1 表示不合格
607
+     */
608
+    public static double calculateQualityScore(double diff, double limit) {
609
+        double absDiff = Math.abs(diff);
610
+
611
+        // 分档区间阈值
612
+        double threshold1 = limit / 3.0; // 33.3%
613
+        double threshold2 = limit / 2.0; // 50%
614
+        double threshold3 = limit / 4.0 * 3.0; // 75%
615
+
616
+        if (absDiff <= threshold1) {
617
+            // 第一档:100分
618
+            return 100.0;
619
+        } else if (absDiff <= threshold2) {
620
+            // 第二档:90~100分(线性插值)
621
+            double scoreMin = 90.0;
622
+            double scoreMax = 100.0;
623
+            double valueMin = threshold1;
624
+            double valueMax = threshold2;
625
+            return scoreMin + (scoreMax - scoreMin) / (valueMax - valueMin) * (absDiff - valueMin);
626
+        } else if (absDiff <= threshold3) {
627
+            // 第三档:75~90分(线性插值)
628
+            double scoreMin = 75.0;
629
+            double scoreMax = 90.0;
630
+            double valueMin = threshold2;
631
+            double valueMax = threshold3;
632
+            return scoreMin + (scoreMax - scoreMin) / (valueMax - valueMin) * (absDiff - valueMin);
633
+        } else if (absDiff <= limit) {
634
+            // 第四档:60~75分(线性插值)
635
+            double scoreMin = 60.0;
636
+            double scoreMax = 75.0;
637
+            double valueMin = threshold3;
638
+            double valueMax = limit;
639
+            return scoreMin + (scoreMax - scoreMin) / (valueMax - valueMin) * (absDiff - valueMin);
640
+        } else {
641
+            // 超限:不合格
642
+            return -1.0;
643
+        }
644
+    }
645
+
646
+
647
+    private double calculategamma(CmcNonparallelismCorrection item) {
648
+        double X = item.getCoordinateX();
649
+        double Y = item.getCoordinateY();
650
+        double band = item.getZoneNo();
651
+        double bandwidth = item.getBandWidth();
652
+        String latitudePosition = item.getLatitudePosition();
653
+        String longitudePosition = item.getLongitudePosition();
654
+        double projectionHeight = item.getProjectionHeight();
655
+
656
+        double x = latitudePosition.equals("S") ? 10000000 - X : X;
657
+        double y = Y > 1.0E+7 ? Y - (int) Math.floor(Y / 1.0E+6) * 1.0E+6 - 500000 : Y - 500000;
658
+
659
+        double bf = calculateBf(x, projectionHeight);
660
+        double tf = Math.tan(bf);
661
+        double ep2 = 1 / Math.pow(1 - F, 2) - 1;
662
+        double etaf2 = ep2 * Math.pow(Math.cos(bf), 2);
663
+        double Vf = Math.sqrt(1 + etaf2);
664
+        double c = (A + projectionHeight) / (1 - F);
665
+        double n = y * Vf / c;
666
+
667
+        // 最终纬度 B
668
+        double B = calculateB(bf, tf, etaf2, n);
669
+
670
+        // 计算L
671
+        double L = calculateL(bf, tf, etaf2, n, longitudePosition, bandwidth, band);
672
+        // 大地经度和大地纬度
673
+        double longitude = convertDecimalDegrees(L);
674
+        double latitude = convertDecimalDegrees(B);
675
+        item.setGeodeticLongitude(longitude);
676
+        item.setGeodeticLatitude(latitude);
677
+
678
+        double gamma = 978030 * (1 + 0.005302 * Math.pow(Math.sin(B / 180 * Math.PI), 2) - 
679
+        0.000007 * Math.pow(Math.sin(2 * B / 180 * Math.PI), 2));
680
+        return gamma;
681
+    }
682
+
683
+    // 计算bf
684
+    private double calculateBf(double x, double projectionHeight) {
685
+        double e2 = E2;
686
+        double e4 = E2 * E2;
687
+        double e6 = e4 * E2;
688
+        double e8 = e6 * E2;
689
+        double e10 = e8 * E2;
690
+        double d = A + projectionHeight;
691
+        // 计算子午线弧长系数
692
+        double a0 = (d - d * e2) * (1
693
+                + 3.0 / 4.0 * e2
694
+                + 45.0 / 64.0 * e4
695
+                + 175.0 / 256.0 * e6
696
+                + 11025.0 / 16384.0 * e8
697
+                + 43659.0 / 65536.0 * e10);
698
+
699
+        double a2 = (d - d * e2) * (3.0 / 4.0 * e2
700
+                + 45.0 / 64.0 * e4
701
+                + 175.0 / 256.0 * e6
702
+                + 11025.0 / 16384.0 * e8
703
+                + 43659.0 / 65536.0 * e10);
704
+
705
+        double a4 = (d - d * e2) * (15.0 / 32.0 * e4
706
+                + 175.0 / 384.0 * e6
707
+                + 3675.0 / 8192.0 * e8
708
+                + 14553.0 / 32768.0 * e10);
709
+
710
+        double a6 = (d - d * e2) * (35.0 / 96.0 * e6
711
+                + 735.0 / 2048.0 * e8
712
+                + 14553.0 / 40960.0 * e10);
713
+
714
+        double a8 = (d - d * e2) * (315.0 / 1024.0 * e8
715
+                + 6237.0 / 20480.0 * e10);
716
+
717
+        double b = x / a0;
718
+        double sinB = Math.sin(b);
719
+        double cosB = Math.cos(b);
720
+        double f = -(a2 * sinB + a4 * Math.pow(sinB, 3) + a6 * Math.pow(sinB, 5) + a8 * Math.pow(sinB, 7)) * cosB;
721
+
722
+        for (int i = 0; i < 9; i++) {
723
+            b = (x - f) / a0;
724
+            sinB = Math.sin(b);
725
+            cosB = Math.cos(b);
726
+            f = -(a2 * sinB + a4 * Math.pow(sinB, 3) + a6 * Math.pow(sinB, 5) + a8 * Math.pow(sinB, 7)) * cosB;
727
+            i++;
728
+        }
729
+        return b;
730
+    }
731
+
732
+    //计算B
733
+    private double calculateB(double bf, double tf, double etaf2, double n) {        double n2 = n * n;
734
+        double n4 = n2 * n2;
735
+        double n6 = n4 * n2;
736
+        // 计算底点纬度对应的值
737
+        double term1 = bf * 180 / Math.PI; // 转为度
738
+        // 计算括号内的各项
739
+        double bracket = 90 * n2
740
+                - 7.5 * (5 + 3 * tf * tf + etaf2 - 9 * etaf2 * tf * tf) * n4
741
+                + 0.25 * (61 + 90 * tf * tf + 45 * tf * tf * tf * tf) * n6;
742
+        // 计算第二项
743
+        double term2 = (1 + etaf2) / Math.PI * tf * bracket;
744
+        // 最终纬度 B
745
+        double B = term1 - term2;
746
+        return B;
747
+    }
748
+
749
+    //计算l
750
+    private double calculateL(double bf, double tf, double etaf2, double n, String longitudePosition,
751
+            double bandwidth, double band) {
752
+        double n2 = n * n;
753
+        double n3 = n2 * n;
754
+        double n5 = n3 * n2;
755
+        double tf2 = tf * tf;
756
+        double tf4 = tf2 * tf2;
757
+        // 括号内计算
758
+        double bracket2 = 180 * n
759
+                - 30 * (1 + 2 * tf2 + etaf2) * n3
760
+                + 1.5 * (5 + 28 * tf2 + 24 * tf4) * n5;
761
+        double l = 1 / Math.PI / Math.cos(bf) * bracket2;
762
+
763
+        double L = "W".equals(longitudePosition)
764
+                ? (bandwidth == 6 ? (band * bandwidth - 3 - l) : (band * bandwidth - l))
765
+                : (bandwidth == 6 ? (l + band * bandwidth - 3) : (l + band * bandwidth));
766
+        return L;
767
+    }
768
+    
769
+    private static double convertDecimalDegrees(double decimalDegrees) {
770
+
771
+        final double PRECISION = 1.2e-12; // 修正值
772
+        final double SEC_PRECISION = 1e-11; // 秒的修正值
773
+
774
+        // 提取度
775
+        double degrees = Math.floor(decimalDegrees + PRECISION);
776
+        // 提取分
777
+        double minutesRaw = 60 * (decimalDegrees - degrees);
778
+        double minutes = Math.floor(minutesRaw + PRECISION) / 100;
779
+        // 提取秒(高精度)
780
+        double secondsRaw = (decimalDegrees * 60 - Math.floor(decimalDegrees * 60 + PRECISION)) * 60;
781
+        double seconds = Math.floor((secondsRaw + SEC_PRECISION) * 1000000) / 10000000000.0;
782
+        
783
+        return degrees + minutes + seconds;
784
+    }
785
+}

+ 40
- 15
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/impl/CmcSpatialToGeodeticServiceImpl.java Просмотреть файл

@@ -271,16 +271,16 @@ public class CmcSpatialToGeodeticServiceImpl implements ICmcSpatialToGeodeticSer
271 271
     }
272 272
 
273 273
     /**
274
-     * 单条空间直角坐标转大地坐标计算(待实现)
274
+     * 单条空间直角坐标转大地坐标计算
275 275
      */
276 276
     private CmcSpatialToGeodetic calculateSpatialToGeodeticSingle(CmcSpatialToGeodetic cmcSpatialToGeodetic) {
277 277
         // 获取输入值
278
-        String coordinateSystem = cmcSpatialToGeodetic.getCoordinateSystem(); // 坐标系
279
-        double spatialX = cmcSpatialToGeodetic.getSpatialX(); // 空间坐标X
280
-        Double spatialY = cmcSpatialToGeodetic.getSpatialY(); // 空间坐标Y
281
-        double spatialZ = cmcSpatialToGeodetic.getSpatialZ(); // 空间坐标Z
282
-        double projectionHeight = cmcSpatialToGeodetic.getProjectionHeight(); // 投影高
283
-        double j = 1.5e-12;
278
+        String coordinateSystem = cmcSpatialToGeodetic.getCoordinateSystem();
279
+        double spatialX = cmcSpatialToGeodetic.getSpatialX();
280
+        Double spatialY = cmcSpatialToGeodetic.getSpatialY();
281
+        double spatialZ = cmcSpatialToGeodetic.getSpatialZ();
282
+        double projectionHeight = cmcSpatialToGeodetic.getProjectionHeight();
283
+        String outputFormat = cmcSpatialToGeodetic.getOutputFormat();
284 284
 
285 285
         initEllipsoidParams(coordinateSystem);
286 286
 
@@ -302,14 +302,16 @@ public class CmcSpatialToGeodeticServiceImpl implements ICmcSpatialToGeodeticSer
302 302
 
303 303
         double B = Math.toDegrees(b);
304 304
 
305
-        double longitude = Math.floor(L_degree + j) + 
306
-                           Math.floor((L_degree - Math.floor(L_degree + j)) * 60 + j) / 100.0 + 
307
-                           Math.floor(((L_degree * 60 - Math.floor(L_degree * 60)) * 60 + Math.pow(10, -11)) * Math.pow(10, 6))
308
-                        / Math.pow(10, 10);
309
-        double latitude = Math.floor(B + j) + 
310
-                           Math.floor((B - Math.floor(B + j)) * 60 + j) / 100.0 + 
311
-                           Math.floor(((B * 60 - Math.floor(B * 60)) * 60 + Math.pow(10, -11)) * Math.pow(10, 6))
312
-                        / Math.pow(10, 10);
305
+        // 大地经度和大地纬度
306
+        double longitude = L_degree;
307
+        double latitude = B;
308
+        
309
+        // 如果输出格式为度分秒(dms),则转换为度分秒格式
310
+        if ("dms".equalsIgnoreCase(outputFormat)) {
311
+            longitude = convertDecimalDegrees(longitude);
312
+            latitude = convertDecimalDegrees(latitude);
313
+        }
314
+        
313 315
         String longitudePosition = spatialY < 0 ? "W" : "E";
314 316
         String latitudePosition = spatialZ < 0 ? "S" : "N";
315 317
         double height = Math.sqrt(Math.pow(spatialX, 2) + Math.pow(spatialY, 2) + Math.pow(spatialZ + t, 2)) - N;
@@ -320,6 +322,29 @@ public class CmcSpatialToGeodeticServiceImpl implements ICmcSpatialToGeodeticSer
320 322
         cmcSpatialToGeodetic.setHeight(height);
321 323
         return cmcSpatialToGeodetic;
322 324
     }
325
+    
326
+    /**
327
+     * 将十进制度数转换为度分秒格式数值(DD.MMSSssss)
328
+     * 与高斯反算中相同的方法
329
+     * 
330
+     * @param decimalDegrees 十进制度数
331
+     * @return 度分秒格式数值
332
+     */
333
+    private static double convertDecimalDegrees(double decimalDegrees) {
334
+        final double PRECISION = 1.2e-12;
335
+        final double SEC_PRECISION = 1e-11;
336
+
337
+        // 提取度
338
+        double degrees = Math.floor(decimalDegrees + PRECISION);
339
+        // 提取分
340
+        double minutesRaw = 60 * (decimalDegrees - degrees);
341
+        double minutes = Math.floor(minutesRaw + PRECISION) / 100;
342
+        // 提取秒(高精度)
343
+        double secondsRaw = (decimalDegrees * 60 - Math.floor(decimalDegrees * 60 + PRECISION)) * 60;
344
+        double seconds = Math.floor((secondsRaw + SEC_PRECISION) * 1000000) / 10000000000.0;
345
+        
346
+        return degrees + minutes + seconds;
347
+    }
323 348
 
324 349
     // 选择椭球体参数
325 350
     private void initEllipsoidParams(String coordinateSystem) {

+ 11
- 4
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/impl/CmcUTMNegativeServiceImpl.java Просмотреть файл

@@ -285,10 +285,11 @@ public class CmcUTMNegativeServiceImpl implements ICmcUTMNegativeService
285 285
             
286 286
             double utmX = cmcUTMNagative.getUtmX();
287 287
             double utmY = cmcUTMNagative.getUtmY();
288
-            Integer band = cmcUTMNagative.getBand();
288
+            Double band = cmcUTMNagative.getBand();
289 289
             String longitudePosition = cmcUTMNagative.getLongitudePosition();
290 290
             String latitudePosition = cmcUTMNagative.getLatitudePosition();
291 291
             double projectionHeight = cmcUTMNagative.getProjectionHeight();
292
+            String outputFormat = cmcUTMNagative.getOutputFormat();
292 293
             
293 294
             // UTM使用固定6度带
294 295
             int bandwidth = 6;
@@ -314,9 +315,15 @@ public class CmcUTMNegativeServiceImpl implements ICmcUTMNegativeService
314 315
             double B = calculateB(bf, tf, etaf2, n);
315 316
             // 计算经度 L
316 317
             double L = calculateL(bf, tf, etaf2, n, longitudePosition, bandwidth, band);
317
-            // 大地经度和大地纬度
318
-            double longitude = convertDecimalDegrees(L);
319
-            double latitude = convertDecimalDegrees(B);
318
+
319
+            double longitude = L;
320
+            double latitude = B;
321
+            // 大地经度和大地纬度(默认为度分秒格式)
322
+            if ("dms".equalsIgnoreCase(outputFormat)) {
323
+                longitude = convertDecimalDegrees(longitude);
324
+                latitude = convertDecimalDegrees(latitude);
325
+            }
326
+            
320 327
 
321 328
             cmcUTMNagative.setLongitude(longitude);
322 329
             cmcUTMNagative.setLatitude(latitude);

+ 40
- 8
oa-back/ruoyi-calculate/src/main/java/com/ruoyi/web/calculate/service/impl/CmcUTMPositiveServiceImpl.java Просмотреть файл

@@ -244,16 +244,26 @@ public class CmcUTMPositiveServiceImpl implements ICmcUTMPositiveService
244 244
         try {
245 245
             initEllipsoidParams(cmcUTMPositive.getCoordinateSystem());
246 246
 
247
-            double longitude = cmcUTMPositive.getLongitude(); // 经度(度)
248
-            String longitudePosition = cmcUTMPositive.getLongitudePosition(); // 经度位置(东/西)
249
-            String latitudePosition = cmcUTMPositive.getLatitudePosition(); // 纬度位置(北/南)
250
-            double latitude = cmcUTMPositive.getLatitude(); // 纬度(度)
251
-            Integer band = cmcUTMPositive.getBand(); // 带号
252
-            double projectionHeight = cmcUTMPositive.getProjectionHeight(); // 投影面高程
247
+            double longitude = cmcUTMPositive.getLongitude();
248
+            String longitudePosition = cmcUTMPositive.getLongitudePosition();
249
+            String latitudePosition = cmcUTMPositive.getLatitudePosition();
250
+            double latitude = cmcUTMPositive.getLatitude();
251
+            Double band = cmcUTMPositive.getBand();
252
+            double projectionHeight = cmcUTMPositive.getProjectionHeight();
253
+            String angleFormat = cmcUTMPositive.getAngleFormat();
254
+            double B = latitude * Math.PI / 180;
255
+            double L = longitude;
256
+            // 如果输入格式为度(degree),先转换为度分秒格式
257
+            // if ("degree".equalsIgnoreCase(angleFormat)) {
258
+            //     longitude = convertDegreeToDMS(longitude);
259
+            //     latitude = convertDegreeToDMS(latitude);
260
+            // }
253 261
 
254 262
             // 转换为弧度
255
-            double B = convertDecimalDegrees(latitude) * Math.PI / 180;
256
-            double L = convertDecimalDegrees(longitude);
263
+            if ("dms".equalsIgnoreCase(angleFormat)) {
264
+                B = convertDecimalDegrees(latitude) * Math.PI / 180;
265
+                L = convertDecimalDegrees(longitude);
266
+            }
257 267
            
258 268
             // 计算经差
259 269
             double l = ((30-band)*6+3-L) * Math.PI / 180;
@@ -426,4 +436,26 @@ public class CmcUTMPositiveServiceImpl implements ICmcUTMPositiveService
426 436
 
427 437
         return degrees + minutes + seconds;
428 438
     }
439
+    
440
+    /**
441
+     * 将十进制度数转换为度分秒格式数值(DD.MMSSssss)
442
+     * 与 calculateDegreeToDMSSingle 方法逻辑相同
443
+     * 
444
+     * @param decimalDegrees 十进制度数(如 103.373428195)
445
+     * @return 度分秒格式数值(如 103.22240038)
446
+     */
447
+    private double convertDegreeToDMS(double decimalDegrees) {
448
+        // 1. 提取度
449
+        double degrees = Math.floor(decimalDegrees + 1.0E-13);
450
+        
451
+        // 2. 提取分
452
+        double minutesRaw = 60 * (decimalDegrees - degrees);
453
+        double minutes = Math.floor(minutesRaw + 1.0E-13) / 100;
454
+        
455
+        // 3. 提取秒
456
+        double secondsRaw = 60 * (60 * decimalDegrees - Math.floor(60 * decimalDegrees + 1.0E-13)) + 1.0E-13;
457
+        double seconds = secondsRaw / 10000;
458
+        
459
+        return degrees + minutes + seconds;
460
+    }
429 461
 }

+ 63
- 0
oa-ui/src/api/calculate/nonparallelismcorrection.js Просмотреть файл

@@ -0,0 +1,63 @@
1
+import request from '@/utils/request'
2
+
3
+/**
4
+ * 非平行度修正计算
5
+ */
6
+export function calculate(data) {
7
+    return request({
8
+        url: `/calculate/nonparallelismCorrection/calculate`,
9
+        method: 'post',
10
+        data: data
11
+    })
12
+}
13
+
14
+/**
15
+ * 导入Excel数据
16
+ */
17
+export function importExcel(data) {
18
+    return request({
19
+        url: `/calculate/nonparallelismCorrection/import`,
20
+        method: 'post',
21
+        data: data,
22
+        headers: {
23
+            'Content-Type': 'multipart/form-data'
24
+        }
25
+    })
26
+}
27
+
28
+/**
29
+ * 导出计算结果
30
+ */
31
+export function exportExcel(data) {
32
+    return request({
33
+        url: `/calculate/nonparallelismCorrection/export`,
34
+        method: 'post',
35
+        data: data,
36
+        responseType: 'blob'
37
+    })
38
+}
39
+
40
+/**
41
+ * 下载导入模板
42
+ */
43
+export function downloadTemplate() {
44
+    return request({
45
+        url: '/calculate/nonparallelismCorrection/template',
46
+        method: 'get',
47
+        responseType: 'blob'
48
+    })
49
+}
50
+
51
+/**
52
+ * 获取工作表名称
53
+ */
54
+export function getSheetNames(data) {
55
+    return request({
56
+        url: '/calculate/nonparallelismCorrection/sheetNames',
57
+        method: 'post',
58
+        data: data,
59
+        headers: {
60
+            'Content-Type': 'multipart/form-data'
61
+        }
62
+    })
63
+}

+ 7
- 1
oa-ui/src/views/calculate/index.vue Просмотреть файл

@@ -56,6 +56,7 @@ import SpatialToGeodeticTool from './tools/spatialtogeodetic.vue'
56 56
 import DegreeToDSTool from './tools/degreetoDMS.vue'
57 57
 import DMStodegreeTool from './tools/DMStodegree.vue'
58 58
 import DegreeToRadianTool from './tools/degreetoradian.vue'
59
+import NonParallelismCorrectionTool from './tools/nonparallelismcorrection.vue'
59 60
 
60 61
 export default {
61 62
   name: 'CalculationTools',
@@ -71,6 +72,7 @@ export default {
71 72
     DegreeToDSTool, 
72 73
     DMStodegreeTool,
73 74
     DegreeToRadianTool,
75
+    NonParallelismCorrectionTool,
74 76
   },
75 77
   data() {
76 78
     return {
@@ -162,7 +164,11 @@ export default {
162 164
           id: 'other-category',
163 165
           name: '其他计算工具',
164 166
           children: [
165
-            // 预留其他工具位置
167
+            {
168
+              id: 'nonparallelism-correction',
169
+              name: '水准测段高差正常水准面不平行改正',
170
+              component: 'NonParallelismCorrectionTool'
171
+            }
166 172
           ]
167 173
         }
168 174
       ]

+ 54
- 9
oa-ui/src/views/calculate/tools/DMStodegree.vue Просмотреть файл

@@ -69,6 +69,19 @@
69 69
           </template>
70 70
         </el-table-column>
71 71
       </el-table>
72
+      
73
+      <!-- 分页组件 -->
74
+      <div class="pagination-wrapper">
75
+        <el-pagination
76
+          @size-change="handleSizeChange"
77
+          @current-change="handleCurrentChange"
78
+          :current-page="currentPage"
79
+          :page-sizes="[100, 200, 500]"
80
+          :page-size="pageSize"
81
+          layout="total, sizes, prev, pager, next, jumper"
82
+          :total="totalData">
83
+        </el-pagination>
84
+      </div>
72 85
     </div>
73 86
     
74 87
     <!-- 空状态 -->
@@ -166,6 +179,10 @@ export default {
166 179
       importFile: null,
167 180
       calculating: false,
168 181
       
182
+      // 分页相关
183
+      currentPage: 1,
184
+      pageSize: 100,
185
+      
169 186
       // 字段映射相关
170 187
       mappingDialogVisible: false,
171 188
       excelColumns: [],
@@ -398,6 +415,17 @@ export default {
398 415
     formatNumber(value, decimals = 3) {
399 416
       if (value === null || value === undefined) return '--'
400 417
       return Number(value).toFixed(decimals)
418
+    },
419
+    
420
+    // 分页大小变化
421
+    handleSizeChange(val) {
422
+      this.pageSize = val
423
+      this.currentPage = 1
424
+    },
425
+    
426
+    // 当前页变化
427
+    handleCurrentChange(val) {
428
+      this.currentPage = val
401 429
     }
402 430
   },
403 431
   
@@ -414,16 +442,11 @@ export default {
414 442
     
415 443
     // 显示数据:优先显示计算结果,否则显示导入数据
416 444
     displayData() {
445
+      let data = []
417 446
       if (this.calculationResults.length > 0) {
418
-        return this.calculationResults.map(item => ({
419
-          pointNumber: item.pointNumber,
420
-          longitudeDMS: item.longitudeDMS,
421
-          latitudeDMS: item.latitudeDMS,
422
-          longitude: item.longitude,
423
-          latitude: item.latitude
424
-        }))
447
+        data = this.calculationResults
425 448
       } else if (this.importedData.length > 0) {
426
-        return this.importedData.map(item => ({
449
+        data = this.importedData.map(item => ({
427 450
           pointNumber: item.pointNumber,
428 451
           longitudeDMS: item.longitudeDMS,
429 452
           latitudeDMS: item.latitudeDMS,
@@ -431,7 +454,19 @@ export default {
431 454
           latitude: undefined
432 455
         }))
433 456
       }
434
-      return []
457
+      
458
+      // 分页处理
459
+      const start = (this.currentPage - 1) * this.pageSize
460
+      const end = start + this.pageSize
461
+      return data.slice(start, end)
462
+    },
463
+    
464
+    // 总数据条数(用于分页组件)
465
+    totalData() {
466
+      if (this.calculationResults.length > 0) {
467
+        return this.calculationResults.length
468
+      }
469
+      return this.importedData.length
435 470
     }
436 471
   }
437 472
 }
@@ -593,4 +628,14 @@ export default {
593 628
   color: #C0C4CC;
594 629
   font-style: italic;
595 630
 }
631
+
632
+.pagination-wrapper {
633
+  display: flex;
634
+  justify-content: flex-end;
635
+  padding: 12px 16px;
636
+  background: #f5f7fa;
637
+  border-radius: 0 0 8px 8px;
638
+  border: 1px solid #e4e7ed;
639
+  border-top: none;
640
+}
596 641
 </style>

+ 54
- 9
oa-ui/src/views/calculate/tools/degreetoDMS.vue Просмотреть файл

@@ -69,6 +69,19 @@
69 69
           </template>
70 70
         </el-table-column>
71 71
       </el-table>
72
+      
73
+      <!-- 分页组件 -->
74
+      <div class="pagination-wrapper">
75
+        <el-pagination
76
+          @size-change="handleSizeChange"
77
+          @current-change="handleCurrentChange"
78
+          :current-page="currentPage"
79
+          :page-sizes="[100, 200, 500]"
80
+          :page-size="pageSize"
81
+          layout="total, sizes, prev, pager, next, jumper"
82
+          :total="totalData">
83
+        </el-pagination>
84
+      </div>
72 85
     </div>
73 86
     
74 87
     <!-- 空状态 -->
@@ -166,6 +179,10 @@ export default {
166 179
       importFile: null,
167 180
       calculating: false,
168 181
       
182
+      // 分页相关
183
+      currentPage: 1,
184
+      pageSize: 100,
185
+      
169 186
       // 字段映射相关
170 187
       mappingDialogVisible: false,
171 188
       excelColumns: [],
@@ -394,6 +411,17 @@ export default {
394 411
     formatNumber(value, decimals = 3) {
395 412
       if (value === null || value === undefined) return '--'
396 413
       return Number(value).toFixed(decimals)
414
+    },
415
+    
416
+    // 分页大小变化
417
+    handleSizeChange(val) {
418
+      this.pageSize = val
419
+      this.currentPage = 1
420
+    },
421
+    
422
+    // 当前页变化
423
+    handleCurrentChange(val) {
424
+      this.currentPage = val
397 425
     }
398 426
   },
399 427
   
@@ -410,16 +438,11 @@ export default {
410 438
     
411 439
     // 显示数据:优先显示计算结果,否则显示导入数据
412 440
     displayData() {
441
+      let data = []
413 442
       if (this.calculationResults.length > 0) {
414
-        return this.calculationResults.map(item => ({
415
-          pointNumber: item.pointNumber,
416
-          longitude: item.longitude,
417
-          latitude: item.latitude,
418
-          longitudeDMS: item.longitudeDMS,
419
-          latitudeDMS: item.latitudeDMS,
420
-        }))
443
+        data = this.calculationResults
421 444
       } else if (this.importedData.length > 0) {
422
-        return this.importedData.map(item => ({
445
+        data = this.importedData.map(item => ({
423 446
           pointNumber: item.pointNumber,
424 447
           longitude: item.longitude,
425 448
           latitude: item.latitude,
@@ -427,7 +450,19 @@ export default {
427 450
           latitudeDMS: undefined,
428 451
         }))
429 452
       }
430
-      return []
453
+      
454
+      // 分页处理
455
+      const start = (this.currentPage - 1) * this.pageSize
456
+      const end = start + this.pageSize
457
+      return data.slice(start, end)
458
+    },
459
+    
460
+    // 总数据条数(用于分页组件)
461
+    totalData() {
462
+      if (this.calculationResults.length > 0) {
463
+        return this.calculationResults.length
464
+      }
465
+      return this.importedData.length
431 466
     }
432 467
   }
433 468
 }
@@ -589,4 +624,14 @@ export default {
589 624
   color: #C0C4CC;
590 625
   font-style: italic;
591 626
 }
627
+
628
+.pagination-wrapper {
629
+  display: flex;
630
+  justify-content: flex-end;
631
+  padding: 12px 16px;
632
+  background: #f5f7fa;
633
+  border-radius: 0 0 8px 8px;
634
+  border: 1px solid #e4e7ed;
635
+  border-top: none;
636
+}
592 637
 </style>

+ 54
- 3
oa-ui/src/views/calculate/tools/degreetoradian.vue Просмотреть файл

@@ -68,6 +68,19 @@
68 68
           </template>
69 69
         </el-table-column>
70 70
       </el-table>
71
+      
72
+      <!-- 分页组件 -->
73
+      <div class="pagination-wrapper">
74
+        <el-pagination
75
+          @size-change="handleSizeChange"
76
+          @current-change="handleCurrentChange"
77
+          :current-page="currentPage"
78
+          :page-sizes="[100, 200, 500]"
79
+          :page-size="pageSize"
80
+          layout="total, sizes, prev, pager, next, jumper"
81
+          :total="totalData">
82
+        </el-pagination>
83
+      </div>
71 84
     </div>
72 85
     
73 86
     <!-- 空状态 -->
@@ -164,6 +177,9 @@ export default {
164 177
       importLoading: false,
165 178
       importFile: null,
166 179
       calculating: false,
180
+      // 分页相关
181
+      currentPage: 1,
182
+      pageSize: 100,
167 183
       // 字段映射相关
168 184
       mappingDialogVisible: false,
169 185
       excelColumns: [],
@@ -180,8 +196,9 @@ export default {
180 196
       return this.fieldMapping.pointNumber && this.fieldMapping.longitude && this.fieldMapping.latitude
181 197
     },
182 198
     displayData() {
199
+      let data = []
183 200
       if (this.calculationResults.length > 0) {
184
-        return this.calculationResults.map(item => ({
201
+        data = this.calculationResults.map(item => ({
185 202
           pointNumber: item.pointNumber,
186 203
           longitude: item.longitude,
187 204
           latitude: item.latitude,
@@ -189,7 +206,7 @@ export default {
189 206
           latitudeRadian: item.latitudeRadian
190 207
         }))
191 208
       } else if (this.importedData.length > 0) {
192
-        return this.importedData.map(item => ({
209
+        data = this.importedData.map(item => ({
193 210
           pointNumber: item.pointNumber,
194 211
           longitude: item.longitude,
195 212
           latitude: item.latitude,
@@ -197,7 +214,19 @@ export default {
197 214
           latitudeRadian: undefined
198 215
         }))
199 216
       }
200
-      return []
217
+      
218
+      // 分页处理
219
+      const start = (this.currentPage - 1) * this.pageSize
220
+      const end = start + this.pageSize
221
+      return data.slice(start, end)
222
+    },
223
+    
224
+    // 总数据条数(用于分页组件)
225
+    totalData() {
226
+      if (this.calculationResults.length > 0) {
227
+        return this.calculationResults.length
228
+      }
229
+      return this.importedData.length
201 230
     }
202 231
   },
203 232
   methods: {
@@ -407,6 +436,17 @@ export default {
407 436
     formatNumber(value, decimals = 3) {
408 437
       if (value === null || value === undefined) return '--'
409 438
       return Number(value).toFixed(decimals)
439
+    },
440
+    
441
+    // 分页大小变化
442
+    handleSizeChange(val) {
443
+      this.pageSize = val
444
+      this.currentPage = 1
445
+    },
446
+    
447
+    // 当前页变化
448
+    handleCurrentChange(val) {
449
+      this.currentPage = val
410 450
     }
411 451
   }
412 452
 }
@@ -561,4 +601,15 @@ export default {
561 601
   flex: 1;
562 602
   min-width: 200px;
563 603
 }
604
+
605
+/* 分页组件样式 */
606
+.pagination-wrapper {
607
+  padding: 12px 16px;
608
+  background: #fff;
609
+  border-radius: 0 0 8px 8px;
610
+  border: 1px solid #e4e7ed;
611
+  border-top: none;
612
+  display: flex;
613
+  justify-content: flex-end;
614
+}
564 615
 </style>

+ 58
- 7
oa-ui/src/views/calculate/tools/gaussbandchange.vue Просмотреть файл

@@ -72,7 +72,7 @@
72 72
       <div class="params-row" style="margin-top: 15px;">
73 73
         <div class="params-group">
74 74
           <label class="param-label">带号</label>
75
-          <el-input v-model.number="commonParams.band" size="small" style="width: 80px;" placeholder="带号" @change="onParamsChange"></el-input>
75
+          <el-input-number v-model="commonParams.band" size="small" :precision="3" :step="0.1" :controls="false" style="width: 80px;" placeholder="带号" @change="onParamsChange"></el-input-number>
76 76
         </div>
77 77
         
78 78
         <div class="params-group">
@@ -85,7 +85,7 @@
85 85
         
86 86
         <div class="params-group">
87 87
           <label class="param-label">新带号</label>
88
-          <el-input v-model.number="commonParams.newBand" size="small" style="width: 80px;" placeholder="新带号" @change="onParamsChange"></el-input>
88
+          <el-input-number v-model="commonParams.newBand" size="small" :precision="3" :step="0.1" :controls="false" style="width: 80px;" placeholder="新带号" @change="onParamsChange"></el-input-number>
89 89
         </div>
90 90
         
91 91
         <div class="params-group">
@@ -143,6 +143,19 @@
143 143
           </template>
144 144
         </el-table-column>
145 145
       </el-table>
146
+      
147
+      <!-- 分页组件 -->
148
+      <div class="pagination-wrapper">
149
+        <el-pagination
150
+          @size-change="handleSizeChange"
151
+          @current-change="handleCurrentChange"
152
+          :current-page="currentPage"
153
+          :page-sizes="[100, 200, 500]"
154
+          :page-size="pageSize"
155
+          layout="total, sizes, prev, pager, next, jumper"
156
+          :total="totalData">
157
+        </el-pagination>
158
+      </div>
146 159
     </div>
147 160
     
148 161
     <!-- 空状态 -->
@@ -246,12 +259,16 @@ export default {
246 259
         coordinateSystem: 'CGCS2000',
247 260
         longitudePosition: 'E',
248 261
         latitudePosition: 'N',
249
-        band: 0,
262
+        band: 0.0,
250 263
         bandwidth: 3,
251
-        newBand: 0,
264
+        newBand: 0.0,
252 265
         newBandwidth: 3
253 266
       },
254 267
       
268
+      // 分页相关
269
+      currentPage: 1,
270
+      pageSize: 100,
271
+      
255 272
       // 字段映射相关
256 273
       mappingDialogVisible: false,
257 274
       excelColumns: [],
@@ -523,6 +540,17 @@ export default {
523 540
     return Number(value).toFixed(decimals)
524 541
   },
525 542
   
543
+  // 分页大小变化
544
+  handleSizeChange(val) {
545
+    this.pageSize = val
546
+    this.currentPage = 1
547
+  },
548
+  
549
+  // 当前页变化
550
+  handleCurrentChange(val) {
551
+    this.currentPage = val
552
+  },
553
+  
526 554
   // 获取坐标系标签类型
527 555
   getCoordinateType(system) {
528 556
     const types = {
@@ -548,8 +576,9 @@ export default {
548 576
     
549 577
     // 显示数据:优先显示计算结果,否则显示导入数据
550 578
     displayData() {
579
+      let data = []
551 580
       if (this.calculationResults.length > 0) {
552
-        return this.calculationResults.map(item => ({
581
+        data = this.calculationResults.map(item => ({
553 582
           pointNumber: item.pointNumber,
554 583
           gaussX: item.gaussX,
555 584
           gaussY: item.gaussY,
@@ -557,7 +586,7 @@ export default {
557 586
           newGaussY: item.newGaussY
558 587
         }))
559 588
       } else if (this.importedData.length > 0) {
560
-        return this.importedData.map(item => ({
589
+        data = this.importedData.map(item => ({
561 590
           pointNumber: item.pointNumber,
562 591
           gaussX: item.gaussX,
563 592
           gaussY: item.gaussY,
@@ -565,7 +594,19 @@ export default {
565 594
           newGaussY: undefined
566 595
         }))
567 596
       }
568
-      return []
597
+      
598
+      // 分页处理
599
+      const start = (this.currentPage - 1) * this.pageSize
600
+      const end = start + this.pageSize
601
+      return data.slice(start, end)
602
+    },
603
+    
604
+    // 总数据条数(用于分页组件)
605
+    totalData() {
606
+      if (this.calculationResults.length > 0) {
607
+        return this.calculationResults.length
608
+      }
609
+      return this.importedData.length
569 610
     }
570 611
   }
571 612
 }
@@ -656,6 +697,16 @@ export default {
656 697
   font-weight: 500;
657 698
 }
658 699
 
700
+.pagination-wrapper {
701
+  display: flex;
702
+  justify-content: flex-end;
703
+  padding: 12px 16px;
704
+  background: #f5f7fa;
705
+  border-radius: 0 0 8px 8px;
706
+  border: 1px solid #e4e7ed;
707
+  border-top: none;
708
+}
709
+
659 710
 .empty-state {
660 711
   text-align: center;
661 712
   padding: 60px 20px;

+ 71
- 9
oa-ui/src/views/calculate/tools/gaussnegative.vue Просмотреть файл

@@ -70,7 +70,7 @@
70 70
         
71 71
         <div class="params-group">
72 72
           <label class="param-label">带号</label>
73
-          <el-input v-model.number="commonParams.band" size="small" style="width: 80px;" placeholder="带号" @change="onParamsChange"></el-input>
73
+          <el-input-number v-model="commonParams.band" size="small" :precision="3" :step="0.1" :controls="false" style="width: 80px;" placeholder="带号" @change="onParamsChange"></el-input-number>
74 74
         </div>
75 75
         
76 76
         <div class="params-group">
@@ -80,6 +80,14 @@
80 80
             <el-option label="6" :value="6"></el-option>
81 81
           </el-select>
82 82
         </div>
83
+        
84
+        <div class="params-group">
85
+          <label class="param-label">输出格式</label>
86
+          <el-select v-model="commonParams.outputFormat" size="small" style="width: 120px;">
87
+            <el-option label="度分秒" value="dms"></el-option>
88
+            <el-option label="度" value="degree"></el-option>
89
+          </el-select>
90
+        </div>
83 91
       </div>
84 92
     </div>
85 93
 
@@ -123,6 +131,19 @@
123 131
           </template>
124 132
         </el-table-column>
125 133
       </el-table>
134
+      
135
+      <!-- 分页组件 -->
136
+      <div class="pagination-wrapper">
137
+        <el-pagination
138
+          @size-change="handleSizeChange"
139
+          @current-change="handleCurrentChange"
140
+          :current-page="currentPage"
141
+          :page-sizes="[100, 200, 500]"
142
+          :page-size="pageSize"
143
+          layout="total, sizes, prev, pager, next, jumper"
144
+          :total="totalData">
145
+        </el-pagination>
146
+      </div>
126 147
     </div>
127 148
     
128 149
     <!-- 空状态 -->
@@ -235,9 +256,14 @@ export default {
235 256
         coordinateSystem: 'CGCS2000',
236 257
         longitudePosition: 'E',
237 258
         latitudePosition: 'N',
238
-        band: 0,
239
-        bandwidth: 3
240
-      }
259
+        band: 0.0,
260
+        bandwidth: 3,
261
+        outputFormat: 'degree'
262
+      },
263
+      
264
+      // 分页相关
265
+      currentPage: 1,
266
+      pageSize: 100,
241 267
     }
242 268
   },
243 269
   watch: {
@@ -361,7 +387,8 @@ export default {
361 387
         longitudePosition: 'E',
362 388
         latitudePosition: 'N',
363 389
         band: 3,
364
-        bandwidth: 3
390
+        bandwidth: 3,
391
+        outputFormat: 'degree'
365 392
       }
366 393
     },
367 394
     
@@ -401,7 +428,8 @@ export default {
401 428
         latitudePosition: this.commonParams.latitudePosition,
402 429
         band: this.commonParams.band,
403 430
         bandwidth: this.commonParams.bandwidth,
404
-        projectionHeight: this.projectionHeight
431
+        projectionHeight: this.projectionHeight,
432
+        outputFormat: this.commonParams.outputFormat
405 433
       }))
406 434
       
407 435
       const response = await calculate(requestData)
@@ -448,6 +476,17 @@ export default {
448 476
       return Number(value).toFixed(decimals)
449 477
     },
450 478
     
479
+    // 分页大小变化
480
+    handleSizeChange(val) {
481
+      this.pageSize = val
482
+      this.currentPage = 1
483
+    },
484
+    
485
+    // 当前页变化
486
+    handleCurrentChange(val) {
487
+      this.currentPage = val
488
+    },
489
+    
451 490
     // 导出结果
452 491
     async handleExport() {
453 492
       if (this.calculationResults.length === 0) {
@@ -508,8 +547,9 @@ export default {
508 547
     
509 548
     // 显示数据:优先显示计算结果,否则显示导入数据
510 549
     displayData() {
550
+      let data = []
511 551
       if (this.calculationResults.length > 0) {
512
-        return this.calculationResults.map(item => ({
552
+        data = this.calculationResults.map(item => ({
513 553
           pointNumber: item.pointNumber,
514 554
           gaussX: item.gaussX,
515 555
           gaussY: item.gaussY,
@@ -517,7 +557,7 @@ export default {
517 557
           latitude: item.latitude
518 558
         }))
519 559
       } else if (this.importedData.length > 0) {
520
-        return this.importedData.map(item => ({
560
+        data = this.importedData.map(item => ({
521 561
           pointNumber: item.pointNumber,
522 562
           gaussX: item.gaussX,
523 563
           gaussY: item.gaussY,
@@ -525,7 +565,19 @@ export default {
525 565
           latitude: undefined
526 566
         }))
527 567
       }
528
-      return []
568
+      
569
+      // 分页处理
570
+      const start = (this.currentPage - 1) * this.pageSize
571
+      const end = start + this.pageSize
572
+      return data.slice(start, end)
573
+    },
574
+    
575
+    // 总数据条数(用于分页组件)
576
+    totalData() {
577
+      if (this.calculationResults.length > 0) {
578
+        return this.calculationResults.length
579
+      }
580
+      return this.importedData.length
529 581
     }
530 582
   },
531 583
     
@@ -617,6 +669,16 @@ export default {
617 669
   font-weight: 500;
618 670
 }
619 671
 
672
+.pagination-wrapper {
673
+  display: flex;
674
+  justify-content: flex-end;
675
+  padding: 12px 16px;
676
+  background: #f5f7fa;
677
+  border-radius: 0 0 8px 8px;
678
+  border: 1px solid #e4e7ed;
679
+  border-top: none;
680
+}
681
+
620 682
 .empty-state {
621 683
   text-align: center;
622 684
   padding: 60px 20px;

+ 74
- 10
oa-ui/src/views/calculate/tools/gausspositive.vue Просмотреть файл

@@ -70,7 +70,7 @@
70 70
         
71 71
         <div class="params-group">
72 72
           <label class="param-label">带号</label>
73
-          <el-input v-model.number="commonParams.band" size="small" style="width: 80px;" placeholder="带号"></el-input>
73
+          <el-input-number v-model="commonParams.band" size="small" :precision="3" :step="0.1" :controls="false" style="width: 80px;" placeholder="带号"></el-input-number>
74 74
         </div>
75 75
         
76 76
         <div class="params-group">
@@ -80,6 +80,16 @@
80 80
             <el-option label="6" :value="6"></el-option>
81 81
           </el-select>
82 82
         </div>
83
+
84
+        
85
+        
86
+        <div class="params-group">
87
+          <label class="param-label">输入数据类型</label>
88
+          <el-select v-model="commonParams.angleFormat" size="small" style="width: 120px;">
89
+            <el-option label="度分秒" value="dms"></el-option>
90
+            <el-option label="度" value="degree"></el-option>
91
+          </el-select>
92
+        </div>
83 93
       </div>
84 94
     </div>
85 95
 
@@ -100,12 +110,12 @@
100 110
       
101 111
       <el-table :data="displayData" style="width: 100%" border stripe>
102 112
         <el-table-column prop="pointNumber" label="待求点号" width="120" align="center"></el-table-column>
103
-        <el-table-column prop="longitude" label="大地经度(° ′ ″)" width="150" align="center">
113
+        <el-table-column prop="longitude" label="大地经度" width="150" align="center">
104 114
           <template slot-scope="scope">
105 115
             {{ formatNumber(scope.row.longitude, 9) }}
106 116
           </template>
107 117
         </el-table-column>
108
-        <el-table-column prop="latitude" label="大地纬度(° ′ ″)" width="150" align="center">
118
+        <el-table-column prop="latitude" label="大地纬度" width="150" align="center">
109 119
           <template slot-scope="scope">
110 120
             {{ formatNumber(scope.row.latitude, 9) }}
111 121
           </template>
@@ -129,6 +139,19 @@
129 139
           </template>
130 140
         </el-table-column>
131 141
       </el-table>
142
+      
143
+      <!-- 分页组件 -->
144
+      <div class="pagination-wrapper">
145
+        <el-pagination
146
+          @size-change="handleSizeChange"
147
+          @current-change="handleCurrentChange"
148
+          :current-page="currentPage"
149
+          :page-sizes="[100, 200, 500]"
150
+          :page-size="pageSize"
151
+          layout="total, sizes, prev, pager, next, jumper"
152
+          :total="totalData">
153
+        </el-pagination>
154
+      </div>
132 155
     </div>
133 156
     
134 157
     <!-- 空状态 -->
@@ -273,7 +296,11 @@ export default {
273 296
       projectionHeight: 0,
274 297
       heightTimer: null,
275 298
       //  预览对话框显示控制
276
-      previewDialogVisible: false, 
299
+      previewDialogVisible: false,
300
+      
301
+      // 分页相关
302
+      currentPage: 1,
303
+      pageSize: 100, 
277 304
       
278 305
       // 字段映射相关
279 306
       fieldMappingVisible: false,
@@ -289,7 +316,8 @@ export default {
289 316
         longitudePosition: 'E',
290 317
         latitudePosition: 'N',
291 318
         band: 0,
292
-        bandwidth: 3
319
+        bandwidth: 3,
320
+        angleFormat: 'degree'
293 321
       }
294 322
     }
295 323
   },
@@ -360,11 +388,12 @@ export default {
360 388
     
361 389
     // 显示数据:优先显示计算结果,否则显示导入数据
362 390
     displayData() {
391
+      let data = []
363 392
       if (this.calculationResults.length > 0) {
364
-        return this.calculationResults
393
+        data = this.calculationResults
365 394
       } else if (this.importedData.length > 0) {
366 395
         // 将导入数据转换为统一格式,保留公共参数信息
367
-        return this.importedData.map(item => ({
396
+        data = this.importedData.map(item => ({
368 397
           pointNumber: item.pointNumber,
369 398
           coordinateSystem: this.commonParams.coordinateSystem,
370 399
           band: this.commonParams.band,
@@ -376,7 +405,19 @@ export default {
376 405
           meridianConvergence: undefined
377 406
         }))
378 407
       }
379
-      return []
408
+      
409
+      // 分页处理
410
+      const start = (this.currentPage - 1) * this.pageSize
411
+      const end = start + this.pageSize
412
+      return data.slice(start, end)
413
+    },
414
+    
415
+    // 总数据条数(用于分页组件)
416
+    totalData() {
417
+      if (this.calculationResults.length > 0) {
418
+        return this.calculationResults.length
419
+      }
420
+      return this.importedData.length
380 421
     }
381 422
   },
382 423
   methods: {
@@ -490,7 +531,8 @@ export default {
490 531
         longitudePosition: 'E',
491 532
         latitudePosition: 'N',
492 533
         band: 3,
493
-        bandwidth: 3
534
+        bandwidth: 3,
535
+        angleFormat: 'degree'
494 536
       }
495 537
     },
496 538
     
@@ -529,7 +571,8 @@ export default {
529 571
         latitudePosition: this.commonParams.latitudePosition,
530 572
         band: this.commonParams.band,
531 573
         bandwidth: this.commonParams.bandwidth,
532
-        projectionHeight: this.commonParams.projectionHeight
574
+        projectionHeight: this.commonParams.projectionHeight,
575
+        angleFormat: this.commonParams.angleFormat
533 576
       }))
534 577
       
535 578
       const response = await calculate(requestData)
@@ -625,6 +668,17 @@ export default {
625 668
     return Number(value).toFixed(decimals)
626 669
   },
627 670
   
671
+  // 分页大小变化
672
+  handleSizeChange(val) {
673
+    this.pageSize = val
674
+    this.currentPage = 1
675
+  },
676
+  
677
+  // 当前页变化
678
+  handleCurrentChange(val) {
679
+    this.currentPage = val
680
+  },
681
+  
628 682
   // 获取坐标系标签类型
629 683
   getCoordinateType(system) {
630 684
     const types = {
@@ -724,6 +778,16 @@ export default {
724 778
   font-weight: 500;
725 779
 }
726 780
 
781
+.pagination-wrapper {
782
+  display: flex;
783
+  justify-content: flex-end;
784
+  padding: 12px 16px;
785
+  background: #f5f7fa;
786
+  border-radius: 0 0 8px 8px;
787
+  border: 1px solid #e4e7ed;
788
+  border-top: none;
789
+}
790
+
727 791
 .empty-state {
728 792
   text-align: center;
729 793
   padding: 60px 20px;

+ 67
- 5
oa-ui/src/views/calculate/tools/geodetictospatial.vue Просмотреть файл

@@ -69,6 +69,14 @@
69 69
             <el-option label="S" value="S"></el-option>
70 70
           </el-select>
71 71
         </div>
72
+        
73
+        <div class="params-group">
74
+          <label class="param-label">角度格式</label>
75
+          <el-select v-model="commonParams.angleFormat" size="small" style="width: 120px;">
76
+            <el-option label="度分秒" value="dms"></el-option>
77
+            <el-option label="度" value="degree"></el-option>
78
+          </el-select>
79
+        </div>
72 80
       </div>
73 81
     </div>
74 82
 
@@ -126,6 +134,19 @@
126 134
           </template>
127 135
         </el-table-column>
128 136
       </el-table>
137
+      
138
+      <!-- 分页组件 -->
139
+      <div class="pagination-wrapper">
140
+        <el-pagination
141
+          @size-change="handleSizeChange"
142
+          @current-change="handleCurrentChange"
143
+          :current-page="currentPage"
144
+          :page-sizes="[100, 200, 500]"
145
+          :page-size="pageSize"
146
+          layout="total, sizes, prev, pager, next, jumper"
147
+          :total="totalData">
148
+        </el-pagination>
149
+      </div>
129 150
     </div>
130 151
     
131 152
     <!-- 空状态 -->
@@ -235,9 +256,14 @@ export default {
235 256
         coordinateSystem: 'WGS84',
236 257
         projectionHeight: 0,
237 258
         longitudePosition: 'E',
238
-        latitudePosition: 'N'
259
+        latitudePosition: 'N',
260
+        angleFormat: 'dms'
239 261
       },
240 262
       
263
+      // 分页相关
264
+      currentPage: 1,
265
+      pageSize: 100,
266
+      
241 267
       // 字段映射相关
242 268
       mappingDialogVisible: false,
243 269
       excelColumns: [],
@@ -405,7 +431,8 @@ export default {
405 431
         longitudePosition: this.commonParams.longitudePosition,
406 432
         latitude: parseFloat(item.latitude),
407 433
         latitudePosition: this.commonParams.latitudePosition,
408
-        height: parseFloat(item.height) || 0
434
+        height: parseFloat(item.height) || 0,
435
+        angleFormat: this.commonParams.angleFormat
409 436
       }))
410 437
       
411 438
       const response = await calculate(requestData)
@@ -492,6 +519,17 @@ export default {
492 519
       return Number(value).toFixed(decimals)
493 520
     },
494 521
     
522
+    // 分页大小变化
523
+    handleSizeChange(val) {
524
+      this.pageSize = val
525
+      this.currentPage = 1
526
+    },
527
+    
528
+    // 当前页变化
529
+    handleCurrentChange(val) {
530
+      this.currentPage = val
531
+    },
532
+    
495 533
     // 获取坐标系标签类型
496 534
   getCoordinateType(system) {
497 535
     const types = {
@@ -518,8 +556,9 @@ computed: {
518 556
   
519 557
   // 显示数据:优先显示计算结果,否则显示导入数据
520 558
   displayData() {
559
+    let data = []
521 560
     if (this.calculationResults.length > 0) {
522
-      return this.calculationResults.map(item => ({
561
+      data = this.calculationResults.map(item => ({
523 562
         pointNumber: item.pointNumber,
524 563
         longitude: item.longitude,
525 564
         latitude: item.latitude,
@@ -529,7 +568,7 @@ computed: {
529 568
         spatialZ: item.spatialZ
530 569
       }))
531 570
     } else if (this.importedData.length > 0) {
532
-      return this.importedData.map(item => ({
571
+      data = this.importedData.map(item => ({
533 572
         pointNumber: item.pointNumber,
534 573
         longitude: item.longitude,
535 574
         latitude: item.latitude,
@@ -539,7 +578,19 @@ computed: {
539 578
         spatialZ: undefined
540 579
       }))
541 580
     }
542
-    return []
581
+    
582
+    // 分页处理
583
+    const start = (this.currentPage - 1) * this.pageSize
584
+    const end = start + this.pageSize
585
+    return data.slice(start, end)
586
+  },
587
+  
588
+  // 总数据条数(用于分页组件)
589
+  totalData() {
590
+    if (this.calculationResults.length > 0) {
591
+      return this.calculationResults.length
592
+    }
593
+    return this.importedData.length
543 594
   }
544 595
 }
545 596
 }
@@ -744,4 +795,15 @@ computed: {
744 795
   color: #C0C4CC;
745 796
   font-style: italic;
746 797
 }
798
+
799
+/* 分页组件样式 */
800
+.pagination-wrapper {
801
+  padding: 12px 16px;
802
+  background: #fff;
803
+  border-radius: 0 0 8px 8px;
804
+  border: 1px solid #e4e7ed;
805
+  border-top: none;
806
+  display: flex;
807
+  justify-content: flex-end;
808
+}
747 809
 </style>

+ 1238
- 0
oa-ui/src/views/calculate/tools/nonparallelismcorrection.vue
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 89
- 27
oa-ui/src/views/calculate/tools/spatialtogeodetic.vue Просмотреть файл

@@ -52,6 +52,14 @@
52 52
             <el-option label="Xian80" value="Xian80"></el-option>
53 53
           </el-select>
54 54
         </div>
55
+        
56
+        <div class="params-group">
57
+          <label class="param-label">输出格式</label>
58
+          <el-select v-model="commonParams.outputFormat" size="small" style="width: 120px;">
59
+            <el-option label="度分秒" value="dms"></el-option>
60
+            <el-option label="度" value="degree"></el-option>
61
+          </el-select>
62
+        </div>
55 63
       </div>
56 64
     </div>
57 65
 
@@ -121,6 +129,19 @@
121 129
           </template>
122 130
         </el-table-column>
123 131
       </el-table>
132
+      
133
+      <!-- 分页组件 -->
134
+      <div class="pagination-wrapper">
135
+        <el-pagination
136
+          @size-change="handleSizeChange"
137
+          @current-change="handleCurrentChange"
138
+          :current-page="currentPage"
139
+          :page-sizes="[100, 200, 500]"
140
+          :page-size="pageSize"
141
+          layout="total, sizes, prev, pager, next, jumper"
142
+          :total="totalData">
143
+        </el-pagination>
144
+      </div>
124 145
     </div>
125 146
     
126 147
     <!-- 空状态 -->
@@ -228,9 +249,14 @@ export default {
228 249
       // 公共参数
229 250
       commonParams: {
230 251
         projectionHeight: 0,
231
-        coordinateSystem: 'WGS84'
252
+        coordinateSystem: 'WGS84',
253
+        outputFormat: 'dms'
232 254
       },
233 255
       
256
+      // 分页相关
257
+      currentPage: 1,
258
+      pageSize: 100,
259
+      
234 260
       // 字段映射相关
235 261
       mappingDialogVisible: false,
236 262
       excelColumns: [],
@@ -396,7 +422,8 @@ export default {
396 422
         coordinateSystem: this.commonParams.coordinateSystem,
397 423
         spatialX: parseFloat(item.spatialX),
398 424
         spatialY: parseFloat(item.spatialY),
399
-        spatialZ: parseFloat(item.spatialZ)
425
+        spatialZ: parseFloat(item.spatialZ),
426
+        outputFormat: this.commonParams.outputFormat
400 427
       }))
401 428
       
402 429
       const response = await calculate(requestData)
@@ -482,6 +509,17 @@ export default {
482 509
       return Number(value).toFixed(decimals)
483 510
     },
484 511
     
512
+    // 分页大小变化
513
+    handleSizeChange(val) {
514
+      this.pageSize = val
515
+      this.currentPage = 1
516
+    },
517
+    
518
+    // 当前页变化
519
+    handleCurrentChange(val) {
520
+      this.currentPage = val
521
+    },
522
+    
485 523
     // 获取坐标系标签类型
486 524
     getCoordinateType(system) {
487 525
       const types = {
@@ -507,34 +545,47 @@ export default {
507 545
     },
508 546
     
509 547
     // 显示数据:优先显示计算结果,否则显示导入数据
510
-    displayData() {
511
-      if (this.calculationResults.length > 0) {
512
-        return this.calculationResults.map(item => ({
513
-          pointNumber: item.pointNumber,
514
-          spatialX: item.spatialX,
515
-          spatialY: item.spatialY,
516
-          spatialZ: item.spatialZ,
517
-          longitude: item.longitude,
518
-          latitude: item.latitude,
519
-          height: item.height,
520
-          longitudePosition: item.longitudePosition,
521
-          latitudePosition: item.latitudePosition,
522
-        }))
523
-      } else if (this.importedData.length > 0) {
524
-        return this.importedData.map(item => ({
525
-          pointNumber: item.pointNumber,
526
-          spatialX: item.spatialX,
527
-          spatialY: item.spatialY,
528
-          spatialZ: item.spatialZ,
529
-          longitude: undefined,
530
-          latitude: undefined,
531
-          height: undefined
532
-        }))
533
-      }
534
-      return []
548
+  displayData() {
549
+    let data = []
550
+    if (this.calculationResults.length > 0) {
551
+      data = this.calculationResults.map(item => ({
552
+        pointNumber: item.pointNumber,
553
+        spatialX: item.spatialX,
554
+        spatialY: item.spatialY,
555
+        spatialZ: item.spatialZ,
556
+        longitude: item.longitude,
557
+        latitude: item.latitude,
558
+        height: item.height,
559
+        longitudePosition: item.longitudePosition,
560
+        latitudePosition: item.latitudePosition,
561
+      }))
562
+    } else if (this.importedData.length > 0) {
563
+      data = this.importedData.map(item => ({
564
+        pointNumber: item.pointNumber,
565
+        spatialX: item.spatialX,
566
+        spatialY: item.spatialY,
567
+        spatialZ: item.spatialZ,
568
+        longitude: undefined,
569
+        latitude: undefined,
570
+        height: undefined
571
+      }))
572
+    }
573
+    
574
+    // 分页处理
575
+    const start = (this.currentPage - 1) * this.pageSize
576
+    const end = start + this.pageSize
577
+    return data.slice(start, end)
578
+  },
579
+  
580
+  // 总数据条数(用于分页组件)
581
+  totalData() {
582
+    if (this.calculationResults.length > 0) {
583
+      return this.calculationResults.length
535 584
     }
585
+    return this.importedData.length
536 586
   }
537 587
 }
588
+}
538 589
 </script>
539 590
 
540 591
 <style scoped>
@@ -730,4 +781,15 @@ export default {
730 781
   flex: 1;
731 782
   min-width: 200px;
732 783
 }
784
+
785
+/* 分页组件样式 */
786
+.pagination-wrapper {
787
+  padding: 12px 16px;
788
+  background: #fff;
789
+  border-radius: 0 0 8px 8px;
790
+  border: 1px solid #e4e7ed;
791
+  border-top: none;
792
+  display: flex;
793
+  justify-content: flex-end;
794
+}
733 795
 </style>

+ 67
- 12
oa-ui/src/views/calculate/tools/utmnegative.vue Просмотреть файл

@@ -70,7 +70,15 @@
70 70
         
71 71
         <div class="params-group">
72 72
           <label class="param-label">带号</label>
73
-          <el-input v-model.number="commonParams.band" size="small" style="width: 80px;" placeholder="带号" @change="onParamsChange"></el-input>
73
+          <el-input-number v-model="commonParams.band" size="small" :precision="3" :step="0.1" :controls="false" style="width: 80px;" placeholder="带号"></el-input-number>
74
+        </div>
75
+        
76
+        <div class="params-group">
77
+          <label class="param-label">输出格式</label>
78
+          <el-select v-model="commonParams.outputFormat" size="small" style="width: 120px;">
79
+            <el-option label="度分秒" value="dms"></el-option>
80
+            <el-option label="度" value="degree"></el-option>
81
+          </el-select>
74 82
         </div>
75 83
       </div>
76 84
     </div>
@@ -119,6 +127,19 @@
119 127
           </template>
120 128
         </el-table-column>
121 129
       </el-table>
130
+      
131
+      <!-- 分页组件 -->
132
+      <div class="pagination-wrapper">
133
+        <el-pagination
134
+          @size-change="handleSizeChange"
135
+          @current-change="handleCurrentChange"
136
+          :current-page="currentPage"
137
+          :page-sizes="[100, 200, 500]"
138
+          :page-size="pageSize"
139
+          layout="total, sizes, prev, pager, next, jumper"
140
+          :total="totalData">
141
+        </el-pagination>
142
+      </div>
122 143
     </div>
123 144
     
124 145
     <!-- 空状态 -->
@@ -218,12 +239,17 @@ export default {
218 239
       projectionHeight: 0,
219 240
       heightTimer: null,
220 241
       
242
+      // 分页相关
243
+      currentPage: 1,
244
+      pageSize: 100,
245
+      
221 246
       // 公共参数
222 247
       commonParams: {
223 248
         coordinateSystem: 'WGS84',
224 249
         longitudePosition: 'E',
225 250
         latitudePosition: 'N',
226
-        band: 0
251
+        band: 0,
252
+        outputFormat: 'degree'
227 253
       },
228 254
       
229 255
       // 字段映射相关
@@ -407,7 +433,8 @@ export default {
407 433
         band: this.commonParams.band,
408 434
         longitudePosition: this.commonParams.longitudePosition,
409 435
         latitudePosition: this.commonParams.latitudePosition,
410
-        projectionHeight: this.projectionHeight
436
+        projectionHeight: this.projectionHeight,
437
+        outputFormat: this.commonParams.outputFormat
411 438
       }))
412 439
       
413 440
       const response = await calculate(requestData)
@@ -493,6 +520,17 @@ export default {
493 520
     return Number(value).toFixed(decimals)
494 521
   },
495 522
   
523
+  // 分页大小变化
524
+  handleSizeChange(val) {
525
+    this.pageSize = val
526
+    this.currentPage = 1
527
+  },
528
+  
529
+  // 当前页变化
530
+  handleCurrentChange(val) {
531
+    this.currentPage = val
532
+  },
533
+  
496 534
   // 获取坐标系标签类型
497 535
   getCoordinateType(system) {
498 536
     const types = {
@@ -518,16 +556,11 @@ export default {
518 556
     
519 557
     // 显示数据:优先显示计算结果,否则显示导入数据
520 558
     displayData() {
559
+      let data = []
521 560
       if (this.calculationResults.length > 0) {
522
-        return this.calculationResults.map(item => ({
523
-          pointNumber: item.pointNumber,
524
-          utmX: item.utmX,
525
-          utmY: item.utmY,
526
-          longitude: item.longitude,
527
-          latitude: item.latitude
528
-        }))
561
+        data = this.calculationResults
529 562
       } else if (this.importedData.length > 0) {
530
-        return this.importedData.map(item => ({
563
+        data = this.importedData.map(item => ({
531 564
           pointNumber: item.pointNumber,
532 565
           utmX: item.utmX,
533 566
           utmY: item.utmY,
@@ -535,7 +568,19 @@ export default {
535 568
           latitude: undefined
536 569
         }))
537 570
       }
538
-      return []
571
+      
572
+      // 分页处理
573
+      const start = (this.currentPage - 1) * this.pageSize
574
+      const end = start + this.pageSize
575
+      return data.slice(start, end)
576
+    },
577
+    
578
+    // 总数据条数(用于分页组件)
579
+    totalData() {
580
+      if (this.calculationResults.length > 0) {
581
+        return this.calculationResults.length
582
+      }
583
+      return this.importedData.length
539 584
     }
540 585
   }
541 586
 }
@@ -730,4 +775,14 @@ export default {
730 775
   color: #C0C4CC;
731 776
   font-style: italic;
732 777
 }
778
+
779
+.pagination-wrapper {
780
+  display: flex;
781
+  justify-content: flex-end;
782
+  padding: 12px 16px;
783
+  background: #f5f7fa;
784
+  border-radius: 0 0 8px 8px;
785
+  border: 1px solid #e4e7ed;
786
+  border-top: none;
787
+}
733 788
 </style>

+ 84
- 30
oa-ui/src/views/calculate/tools/utmpositive.vue Просмотреть файл

@@ -70,7 +70,15 @@
70 70
         
71 71
         <div class="params-group">
72 72
           <label class="param-label">带号</label>
73
-          <el-input v-model.number="commonParams.band" size="small" style="width: 80px;" placeholder="带号" @change="onParamsChange"></el-input>
73
+          <el-input-number v-model="commonParams.band" size="small" :precision="3" :step="0.1" :controls="false" style="width: 80px;" placeholder="带号"></el-input-number>
74
+        </div>
75
+        
76
+        <div class="params-group">
77
+          <label class="param-label">角度格式</label>
78
+          <el-select v-model="commonParams.angleFormat" size="small" style="width: 120px;">
79
+            <el-option label="度分秒" value="dms"></el-option>
80
+            <el-option label="度" value="degree"></el-option>
81
+          </el-select>
74 82
         </div>
75 83
       </div>
76 84
     </div>
@@ -96,12 +104,12 @@
96 104
       
97 105
       <el-table :data="displayData" style="width: 100%" border stripe>
98 106
         <el-table-column prop="pointNumber" label="待求点号" width="120" align="center"></el-table-column>
99
-        <el-table-column prop="longitude" label="大地经度(° ′ ″)" width="150" align="center">
107
+        <el-table-column prop="longitude" label="大地经度" width="150" align="center">
100 108
           <template slot-scope="scope">
101 109
             <span>{{ formatNumber(scope.row.longitude, 6) }}</span>
102 110
           </template>
103 111
         </el-table-column>
104
-        <el-table-column prop="latitude" label="大地纬度(° ′ ″)" width="150" align="center">
112
+        <el-table-column prop="latitude" label="大地纬度" width="150" align="center">
105 113
           <template slot-scope="scope">
106 114
             <span>{{ formatNumber(scope.row.latitude, 6) }}</span>
107 115
           </template>
@@ -125,6 +133,19 @@
125 133
           </template>
126 134
         </el-table-column>
127 135
       </el-table>
136
+      
137
+      <!-- 分页组件 -->
138
+      <div class="pagination-wrapper">
139
+        <el-pagination
140
+          @size-change="handleSizeChange"
141
+          @current-change="handleCurrentChange"
142
+          :current-page="currentPage"
143
+          :page-sizes="[100, 200, 500]"
144
+          :page-size="pageSize"
145
+          layout="total, sizes, prev, pager, next, jumper"
146
+          :total="totalData">
147
+        </el-pagination>
148
+      </div>
128 149
     </div>
129 150
     
130 151
     <!-- 空状态 -->
@@ -224,12 +245,17 @@ export default {
224 245
       projectionHeight: 0,
225 246
       heightTimer: null,
226 247
       
248
+      // 分页相关
249
+      currentPage: 1,
250
+      pageSize: 100,
251
+      
227 252
       // 公共参数
228 253
       commonParams: {
229 254
         coordinateSystem: 'WGS84',
230 255
         longitudePosition: 'E',
231 256
         latitudePosition: 'N',
232
-        band: 0
257
+        band: 0,
258
+        angleFormat: 'degree'
233 259
       },
234 260
       
235 261
       // 字段映射相关
@@ -413,7 +439,8 @@ export default {
413 439
         latitude: parseFloat(item.latitude),
414 440
         latitudePosition: this.commonParams.latitudePosition,
415 441
         band: this.commonParams.band,
416
-        projectionHeight: this.projectionHeight
442
+        projectionHeight: this.projectionHeight,
443
+        angleFormat: this.commonParams.angleFormat
417 444
       }))
418 445
       
419 446
       const response = await calculate(requestData)
@@ -495,22 +522,33 @@ export default {
495 522
     },
496 523
     
497 524
     // 格式化数字显示
498
-    formatNumber(value, decimals = 3) {
499
-      if (value === null || value === undefined) return '--'
500
-      return Number(value).toFixed(decimals)
501
-    },
502
-    
503
-    // 获取坐标系标签类型
504
-    getCoordinateType(system) {
505
-      const types = {
506
-        'WGS84': 'primary',
507
-        'CGCS2000': 'success',
508
-        'Beijing54': 'warning',
509
-        'Xian80': 'info'
510
-      }
511
-      return types[system] || 'info'
512
-    },
525
+  formatNumber(value, decimals = 3) {
526
+    if (value === null || value === undefined) return '--'
527
+    return Number(value).toFixed(decimals)
528
+  },
529
+  
530
+  // 分页大小变化
531
+  handleSizeChange(val) {
532
+    this.pageSize = val
533
+    this.currentPage = 1
534
+  },
535
+  
536
+  // 当前页变化
537
+  handleCurrentChange(val) {
538
+    this.currentPage = val
539
+  },
540
+  
541
+  // 获取坐标系标签类型
542
+  getCoordinateType(system) {
543
+    const types = {
544
+      'WGS84': 'primary',
545
+      'CGCS2000': 'success',
546
+      'Beijing54': 'warning',
547
+      'Xian80': 'info'
548
+    }
549
+    return types[system] || 'info'
513 550
   },
551
+},
514 552
   
515 553
   computed: {
516 554
     // 验证字段映射
@@ -525,17 +563,11 @@ export default {
525 563
     
526 564
     // 显示数据:优先显示计算结果,否则显示导入数据
527 565
     displayData() {
566
+      let data = []
528 567
       if (this.calculationResults.length > 0) {
529
-        return this.calculationResults.map(item => ({
530
-          pointNumber: item.pointNumber,
531
-          longitude: item.longitude,
532
-          latitude: item.latitude,
533
-          utmX: item.utmX,
534
-          utmY: item.utmY,
535
-          meridianConvergence: item.meridianConvergence
536
-        }))
568
+        data = this.calculationResults
537 569
       } else if (this.importedData.length > 0) {
538
-        return this.importedData.map(item => ({
570
+        data = this.importedData.map(item => ({
539 571
           pointNumber: item.pointNumber,
540 572
           longitude: item.longitude,
541 573
           latitude: item.latitude,
@@ -544,7 +576,19 @@ export default {
544 576
           meridianConvergence: undefined
545 577
         }))
546 578
       }
547
-      return []
579
+      
580
+      // 分页处理
581
+      const start = (this.currentPage - 1) * this.pageSize
582
+      const end = start + this.pageSize
583
+      return data.slice(start, end)
584
+    },
585
+    
586
+    // 总数据条数(用于分页组件)
587
+    totalData() {
588
+      if (this.calculationResults.length > 0) {
589
+        return this.calculationResults.length
590
+      }
591
+      return this.importedData.length
548 592
     }
549 593
   }
550 594
 }
@@ -739,4 +783,14 @@ export default {
739 783
   color: #C0C4CC;
740 784
   font-style: italic;
741 785
 }
786
+
787
+.pagination-wrapper {
788
+  display: flex;
789
+  justify-content: flex-end;
790
+  padding: 12px 16px;
791
+  background: #f5f7fa;
792
+  border-radius: 0 0 8px 8px;
793
+  border: 1px solid #e4e7ed;
794
+  border-top: none;
795
+}
742 796
 </style>

Загрузка…
Отмена
Сохранить