Commit f59b71e3 by zhaopanyu

zpy

parent 1a092ae5
<template> <template>
<div id="app"> <v-app>
<router-view /> <div id="app">
<theme-picker /> <router-view />
</div> <theme-picker />
</div>
</v-app>
</template> </template>
<script> <script>
...@@ -21,6 +23,7 @@ export default { ...@@ -21,6 +23,7 @@ export default {
} }
} }
</script> </script>
<style scoped> <style scoped>
#app .theme-picker { #app .theme-picker {
display: none; display: none;
......
<template>
<div class="style-panel line-style-panel" :class="{ 'style-panel-visible': visible }">
<div class="style-panel-header">
<h3>线条样式</h3>
<el-button icon="el-icon-close" size="mini" circle @click="$emit('close')"></el-button>
</div>
<div class="style-content">
<div class="style-item">
<span class="style-label">颜色:</span>
<el-color-picker v-model="lineStyleValue.color" show-alpha @change="updateStyle">
</el-color-picker>
</div>
<div class="style-item">
<span class="style-label">样式:</span>
<el-select v-model="lineStyleValue.pattern" placeholder="选择线条样式" @change="updateStyle">
<el-option v-for="(pattern, key) in linePatterns" :key="key" :label="key" :value="key">
<div class="pattern-preview-line" :style="getLinePatternStyle(key)"></div>
</el-option>
</el-select>
</div>
<div class="style-item">
<span class="style-label">宽度:</span>
<el-slider v-model="lineStyleValue.width" :min="1" :max="12" show-input
@change="updateStyle">
</el-slider>
</div>
</div>
</div>
</template>
<script>
import { LineStyle } from '@int/geotoolkit/attributes/LineStyle';
import { LINE_PATTERNS, LINESTYLE_PATTERNS } from '@/api/Patterns.js';
export default {
name: 'LineStylePanel',
props: {
visible: {
type: Boolean,
default: false
},
lineStyle: {
type: Object,
default: () => ({
color: '#000000',
width: 2,
pattern: 'Solid'
})
},
linePatterns: {
type: Object,
default: () => LINESTYLE_PATTERNS
}
},
data() {
return {
lineStyleValue: { ...this.lineStyle },
LINE_PATTERNS: LINE_PATTERNS
};
},
watch: {
lineStyle: {
handler(newVal) {
this.lineStyleValue = { ...newVal };
},
deep: true
}
},
methods: {
updateStyle() {
// 发送样式更新事件
this.$emit('update', this.lineStyleValue);
},
getLinePatternStyle(key) {
let dashStyle = '';
// 使用处理后的线条模式
const patternArray = this.getProcessedLinePattern(key);
if (patternArray && patternArray.length > 0) {
dashStyle = patternArray.join('px ') + 'px';
}
return {
background: 'transparent',
backgroundImage: `url(${this.LINE_PATTERNS[key]})`,
backgroundRepeat: 'no-repeat',
backgroundSize: 'contain',
backgroundPosition: 'center',
height: '20px',
width: '100%',
margin: '5px 0'
};
},
getProcessedLinePattern(pattern) {
// 如果pattern是数组,直接返回
if (Array.isArray(pattern)) {
return pattern;
}
// 如果pattern是LINESTYLE_PATTERNS的键,使用该值
if (this.linePatterns && this.linePatterns[pattern]) {
return this.linePatterns[pattern];
}
// 根据常见的模式名称提供默认数组
if (typeof pattern === 'string') {
switch (pattern) {
case 'Dash':
return [20, 4];
case 'Dot':
return [2, 4];
case 'DashDot':
return [20, 4, 2, 4];
case 'DashDotDot':
return [20, 4, 2, 4, 2, 4];
case 'ShortDash':
return [10, 4];
case 'LongDash':
return [40, 4];
case 'DashLongDash':
return [20, 4, 40, 4];
case 'Solid':
case 'None':
default:
return []; // 默认为实线
}
}
// 默认返回空数组(实线)
console.log('使用默认实线模式,无法识别模式:', pattern);
return [];
}
}
};
</script>
<style scoped>
.style-panel {
position: fixed;
right: -300px;
top: 0;
width: 300px;
height: 100vh;
background-color: #fff;
box-shadow: -2px 0 5px rgba(0, 0, 0, 0.1);
transition: right 0.3s ease;
z-index: 1000;
overflow-y: auto;
}
.style-panel-visible {
right: 0;
}
.style-panel-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 15px;
border-bottom: 1px solid #ddd;
}
.style-panel-header h3 {
margin: 0;
font-size: 16px;
}
.style-content {
padding: 15px;
}
.style-item {
margin-bottom: 15px;
}
.style-label {
display: block;
margin-bottom: 5px;
color: #666;
}
.pattern-preview-line {
width: 100%;
height: 20px;
border: 1px solid #ddd;
border-radius: 4px;
}
.el-slider {
margin-top: 8px;
}
.el-color-picker {
width: 100%;
}
.el-select {
width: 100%;
}
</style>
\ No newline at end of file
<template> <template>
<el-dialog :visible.sync="showDialog" width="800px" :before-close="onClose" :title="title" append-to-body> <el-dialog :visible.sync="dialogVisible" width="800px" :before-close="onClose" :title="title" append-to-body>
<el-form :model="dialogData" label-width="120px"> <el-form :model="dialogData" label-width="120px">
<!-- 纸张格式 --> <!-- 纸张格式 -->
<el-form-item label="纸张格式"> <el-form-item label="纸张格式">
...@@ -184,6 +184,7 @@ export default { ...@@ -184,6 +184,7 @@ export default {
}, },
data() { data() {
return { return {
dialogVisible: false,
paperFactory: null, paperFactory: null,
papers: [], papers: [],
orientations: [], orientations: [],
...@@ -206,6 +207,7 @@ export default { ...@@ -206,6 +207,7 @@ export default {
}; };
}, },
created() { created() {
this.dialogVisible = this.showDialog;
this.paperFactory = PaperFormatFactory.getInstance(); this.paperFactory = PaperFormatFactory.getInstance();
this.papers = this.paperFactory.getPaperList(); this.papers = this.paperFactory.getPaperList();
this.orientations = Object.keys(PaperOrientation); this.orientations = Object.keys(PaperOrientation);
...@@ -232,6 +234,18 @@ export default { ...@@ -232,6 +234,18 @@ export default {
this.dialogData.width = +paper.getWidth().toFixed('1'); this.dialogData.width = +paper.getWidth().toFixed('1');
this.dialogData.height = +paper.getHeight().toFixed('1'); this.dialogData.height = +paper.getHeight().toFixed('1');
}, },
watch: {
// 监听外部showDialog属性变化
showDialog(val) {
this.dialogVisible = val;
},
// 监听内部dialogVisible变化,同步到外部
dialogVisible(val) {
if (!val && this.showDialog) {
this.onClose();
}
}
},
methods: { methods: {
getPaper() { getPaper() {
const { paperFormat, units, orientation } = this.dialogData; const { paperFormat, units, orientation } = this.dialogData;
...@@ -250,6 +264,7 @@ export default { ...@@ -250,6 +264,7 @@ export default {
this.$emit('save', { 'printSettings': settings }); this.$emit('save', { 'printSettings': settings });
}, },
onClose() { onClose() {
this.dialogVisible = false;
this.$emit('close'); this.$emit('close');
} }
} }
......
...@@ -38,6 +38,10 @@ import VueMeta from 'vue-meta' ...@@ -38,6 +38,10 @@ import VueMeta from 'vue-meta'
// 字典数据组件 // 字典数据组件
import DictData from '@/components/DictData' import DictData from '@/components/DictData'
// 引入Vuetify
import vuetify from '@/plugins/vuetify'
import '@mdi/font/css/materialdesignicons.css' // Material Design Icons
// 全局方法挂载 // 全局方法挂载
Vue.prototype.getDicts = getDicts Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey Vue.prototype.getConfigKey = getConfigKey
...@@ -82,5 +86,6 @@ new Vue({ ...@@ -82,5 +86,6 @@ new Vue({
el: '#app', el: '#app',
router, router,
store, store,
vuetify, // 添加vuetify实例
render: h => h(App) render: h => h(App)
}) })
package com.seismic.controller;
import com.seismic.model.SeismicMetadata;
import com.seismic.service.SeismicDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.List;
import java.io.File;
@RestController
@RequestMapping("/ndy/dz")
public class SeismicDataController {
@Autowired
private SeismicDataService seismicDataService;
@GetMapping("/getSeismicMetadata")
public ResponseEntity<SeismicMetadata> getMetadata(@RequestParam String fileName) {
try {
SeismicMetadata metadata = seismicDataService.getMetadata(fileName);
return ResponseEntity.ok(metadata);
} catch (IOException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
@GetMapping("/getRemoteSeismicData")
public ResponseEntity<byte[]> getSeismicData(
@RequestParam String fileName,
@RequestHeader(value = HttpHeaders.RANGE, required = false) String rangeHeader) {
try {
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream");
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
byte[] data;
if (rangeHeader != null) {
// 处理范围请求
List<HttpRange> ranges = HttpRange.parseRanges(rangeHeader);
data = seismicDataService.getSeismicData(fileName, ranges);
// 设置范围响应头
HttpRange range = ranges.get(0);
long fileSize = new File(seismicDataPath + fileName).length();
long start = range.getRangeStart(fileSize);
long end = range.getRangeEnd(fileSize);
headers.add(HttpHeaders.CONTENT_RANGE, "bytes " + start + "-" + end + "/" + fileSize);
headers.add(HttpHeaders.ACCEPT_RANGES, "bytes");
return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT)
.headers(headers)
.body(data);
} else {
// 返回完整文件
data = seismicDataService.getSeismicData(fileName, null);
return ResponseEntity.ok()
.headers(headers)
.body(data);
}
} catch (IOException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
}
\ No newline at end of file
package com.seismic.model;
import lombok.Data;
import lombok.Builder;
@Data
@Builder
public class SeismicMetadata {
private Dimensions dimensions;
private Statistics statistics;
private SampleInfo sampleInfo;
@Data
@Builder
public static class Dimensions {
private int traces;
private int samples;
}
@Data
@Builder
public static class Statistics {
private double min;
private double max;
private double rms;
}
@Data
@Builder
public static class SampleInfo {
private double interval;
private String format;
private String unit;
}
}
\ No newline at end of file
package com.seismic.service;
import com.seismic.model.SeismicMetadata;
import org.springframework.stereotype.Service;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpRange;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.List;
@Service
public class SeismicDataService {
private final ResourceLoader resourceLoader;
@Value("${seismic.data.path}")
private String seismicDataPath;
public SeismicDataService(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
public SeismicMetadata getMetadata(String fileName) throws IOException {
File segyFile = new File(seismicDataPath + fileName);
try (RandomAccessFile raf = new RandomAccessFile(segyFile, "r")) {
// 读取SEGY文件头
byte[] binaryHeader = new byte[400];
raf.seek(3200); // 跳过文本头
raf.read(binaryHeader);
// 解析二进制头
ByteBuffer buffer = ByteBuffer.wrap(binaryHeader);
buffer.order(ByteOrder.BIG_ENDIAN);
// 获取采样间隔(微秒)
buffer.position(16);
int sampleInterval = buffer.getShort() & 0xFFFF;
// 获取每道采样数
buffer.position(20);
int samplesPerTrace = buffer.getShort() & 0xFFFF;
// 获取数据格式代码
buffer.position(24);
int formatCode = buffer.getShort() & 0xFFFF;
// 计算道数
long fileSize = segyFile.length();
int traceHeaderSize = 240;
int traceSampleSize = 4; // 假设是4字节浮点数
int traceSize = traceHeaderSize + (samplesPerTrace * traceSampleSize);
int traces = (int)((fileSize - 3600) / traceSize);
// 计算统计信息
double min = Double.MAX_VALUE;
double max = Double.MIN_VALUE;
double sumSquares = 0;
long sampleCount = 0;
byte[] traceData = new byte[samplesPerTrace * 4];
for (int i = 0; i < Math.min(traces, 1000); i++) { // 只读取前1000道以提高性能
raf.seek(3600 + (i * traceSize) + traceHeaderSize);
raf.read(traceData);
ByteBuffer traceBuffer = ByteBuffer.wrap(traceData);
traceBuffer.order(ByteOrder.BIG_ENDIAN);
for (int j = 0; j < samplesPerTrace; j++) {
float value = traceBuffer.getFloat(j * 4);
min = Math.min(min, value);
max = Math.max(max, value);
sumSquares += value * value;
sampleCount++;
}
}
double rms = Math.sqrt(sumSquares / sampleCount);
// 构建元数据对象
return SeismicMetadata.builder()
.dimensions(SeismicMetadata.Dimensions.builder()
.traces(traces)
.samples(samplesPerTrace)
.build())
.statistics(SeismicMetadata.Statistics.builder()
.min(min)
.max(max)
.rms(rms)
.build())
.sampleInfo(SeismicMetadata.SampleInfo.builder()
.interval(sampleInterval)
.format(getFormatString(formatCode))
.unit("ms")
.build())
.build();
}
}
public byte[] getSeismicData(String fileName, List<HttpRange> ranges) throws IOException {
File segyFile = new File(seismicDataPath + fileName);
if (ranges == null || ranges.isEmpty()) {
// 如果没有指定范围,返回整个文件
try (FileInputStream fis = new FileInputStream(segyFile)) {
return fis.readAllBytes();
}
} else {
// 处理范围请求
HttpRange range = ranges.get(0); // 只处理第一个范围
long start = range.getRangeStart(segyFile.length());
long end = range.getRangeEnd(segyFile.length());
int length = (int)(end - start + 1);
byte[] data = new byte[length];
try (RandomAccessFile raf = new RandomAccessFile(segyFile, "r")) {
raf.seek(start);
raf.read(data);
return data;
}
}
}
private String getFormatString(int formatCode) {
switch (formatCode) {
case 1: return "IBM浮点数";
case 2: return "32位定点数";
case 3: return "16位定点数";
case 4: return "带增益码的定点数";
case 5: return "IEEE浮点数";
default: return "未知格式";
}
}
}
\ No newline at end of file
seismic:
data:
path: /path/to/your/segy/files/ # 替换为您的SEGY文件存储路径
\ No newline at end of file
import Vue from 'vue'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
Vue.use(Vuetify)
export default new Vuetify({
theme: {
themes: {
light: {
primary: '#1976D2',
secondary: '#424242',
accent: '#82B1FF',
error: '#FF5252',
info: '#2196F3',
success: '#4CAF50',
warning: '#FFC107'
}
}
},
icons: {
iconfont: 'mdi'
}
})
\ No newline at end of file
<template>
<div>
</div>
</template>
<script>
export default {
}
</script>
<style lang="scss" scoped></style>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -38,7 +38,8 @@ module.exports = { ...@@ -38,7 +38,8 @@ module.exports = {
proxy: { proxy: {
// detail: https://cli.vuejs.org/config/#devserver-proxy // detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: { [process.env.VUE_APP_BASE_API]: {
target: `http://192.168.31.108:8999`, //井测试 // target: `http://192.168.31.108:8999`, //井测试
target: `http://192.168.31.190:8999`, //井测试
changeOrigin: true, changeOrigin: true,
pathRewrite: { pathRewrite: {
["^" + process.env.VUE_APP_BASE_API]: "", ["^" + process.env.VUE_APP_BASE_API]: "",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment