microwave-project-unite/src/components/ration/soilMoisture/index.vue

809 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="soilMositure">
<div class="smBodyLeft">
<div class="smps">
<div class="box1">
<span class="sp1"></span><span class="sp2">样本库</span>
</div>
<div>
<el-form :inline="true" :model="simpleForm" class="demo-form-inline">
<el-form-item>
<el-cascader
v-model="simpleForm.sampleFun"
:disabled="sampleFun !== ''"
:options="funcOpt"
size="mini"
placeholder="请选择抽样方法"
popper-class="cascader-popper"
@change="changeSampleFun"
clearable
:show-all-levels="false"
></el-cascader>
<el-button
v-if="isDeepSpace"
class="edit-btn"
plain
size="mini"
type="primary"
icon="el-icon-edit-outline"
@click="editDeepSpace"
></el-button>
</el-form-item>
<el-form-item>
<el-input
v-model="simpleForm.sampleNum"
size="mini"
placeholder="请输入样本个数"
></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="samplesCk">确定</el-button>
</el-form-item>
</el-form>
<el-table
ref="multipleTable"
v-loading="loading"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
:data="simpleData"
tooltip-effect="dark"
:header-cell-style="headerRowClass"
style="width: 98%; margin-left: 1%"
@selection-change="handleSelectionChange"
:stripe="true"
:cell-style="tableRowClassName"
height="460"
>
<el-table-column type="selection" width="55"> </el-table-column>
<el-table-column label="序号" type="index" width="70">
</el-table-column>
<el-table-column
prop="samplesId"
label="样本编号"
show-overflow-tooltip
min-width="100px;"
>
</el-table-column>
<el-table-column
prop="lat"
label="纬度"
sortable
show-overflow-tooltip
>
</el-table-column>
<el-table-column
prop="lng"
label="经度"
sortable
show-overflow-tooltip
>
</el-table-column>
<!-- <el-table-column :label="smLabel" show-overflow-tooltip>
<template slot-scope="scope">{{
scope.row.paramStr | getSampleVal
}}</template>
</el-table-column> -->
<el-table-column
prop="collectDate"
label="采样时间"
sortable
show-overflow-tooltip
min-width="120px;"
>
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button
type="primary"
size="small"
icon="el-icon-edit"
></el-button>
<el-button
type="danger"
size="small"
icon="el-icon-delete"
@click="deleteSelected(scope.$index, simpleData)"
></el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<div class="smBodyRight">
<div class="box1">
<span class="sp1"></span
><span class="sp2">待检验产品及样本分布结果</span>
</div>
<div
:class="
checkRealityWait ? 'sceneShowContent onBorder' : 'sceneShowContent'
"
id="sceneShowContent"
>
<!-- <div v-show="checkRealityWait" class="topContent">
<span class="mapTitle">待检验{{ productSubType | productTypeMap }}图</span>
</div> -->
<div :id="checkRealityWait ? 'mapContent' : 'cesiumContent'">
<canvas v-show="checkRealityWait" id="grid"></canvas>
<div id="cesiumView" @click="pickValue">
<div v-show="checkRealityWait" class="compass">
<img
src="../../../assets/images/compass_one.svg"
alt=""
style="width: 100%; height: 100%"
/>
</div>
<canvas v-show="checkRealityWait" id="scaleBar"></canvas>
</div>
</div>
<div v-show="checkRealityWait" class="bottomCont">
<span>制图单位:中国科学院空天信息创新研究院</span><br />
<span>制图日期:{{ createImgTime }}</span>
</div>
</div>
</div>
<SampleSetting
:stepSampling="stepSampling"
@handleStepSampling="handleStepSampling"
@handleDepthList="handleDepthList"
:sampleCldFun="sampleCldFun"
ref="sampleSettingPanel"
></SampleSetting>
</div>
</template>
<script>
import {
getSamplesList,
getSampleData,
getSamplesByLayer,
} from "@/api/lang/pendingOrder";
import cu from "@/lib/cesiumUtils";
import SampleSetting from "@/components/ration/sampleSetting/index.vue";
import WKT from "terraformer-wkt-parser";
import Formator from "@/mixins/formator";
import { drawScaleTwo, drawGrid, getNowFormatDate } from "@/lib/utils";
export default {
components: {
SampleSetting,
},
mixins: [Formator],
props: {
sampleFun: {
require: true,
type: String,
},
sampleCldFun: {
require: false,
type: String,
},
pixelFun: {
require: true,
type: String,
},
geoWorkSpace: {
require: true,
type: String,
},
geoLayerName: {
require: true,
type: String,
},
geoLayerPos: {
require: true,
},
pixelNum: {
require: true,
},
orderId: {
require: true,
},
productSubType: {
require: true,
},
checkRealityWait: {
require: true,
},
},
filters: {
getSampleVal(paramStr) {
return JSON.parse(paramStr).featureValue.featureValue;
},
productTypeMap(pdtype) {
const pdtypeMap = {
45: "正射产品",
46: "高程产品",
51: "后向散射系数产品",
52: "大气延迟校正产品",
53: "干涉测量形变产品",
39: "地表覆盖类型产品",
38: "土壤水分产品",
49: "土壤盐碱度产品",
50: "地表粗糙度产品",
48: "植被高度产品",
43: "叶面积指数产品",
47: "植被物候产品",
};
if (pdtype == null) return null;
else return pdtypeMap[pdtype];
},
},
data() {
return {
simpleForm: {
sampleFun: "",
sampleNum: "",
},
simpleData: [],
loading: true,
allSampleData: [],
simpleDataTotal: 0,
smLabel: "土壤水分",
pixelFormData: {
pixelDealFun: "",
},
multipleSelection: [],
pdShow: false,
stepSampling: false,
funcOpt: [],
isDeepSpace: false,
depthList: [],
createImgTime: null,
};
},
mounted() {
cu.initCesium("cesiumView");
cu.handleClick();
cu.addlayer(this.geoWorkSpace, this.geoLayerName);
let gp = this.geoLayerPos;
cu.flyToLayerRect(gp[0], gp[1], gp[2], gp[3]);
},
created() {
this.funcOpt = this.configration.funcOpt;
this.getSplData();
this.initParam();
},
watch: {
checkRealityWait(val) {
const navigationDiv = document.getElementsByClassName(
"cesium-widget-cesiumNavigationContainer"
);
if (val) {
window.selfDefine.viewer.scene.postRender.addEventListener(
this.addScale
);
window.selfDefine.viewer.scene.postRender.addEventListener(
this.addGrid
);
this.createImgTime = getNowFormatDate();
if (navigationDiv) navigationDiv[0].style.display = "none";
} else {
this.removeListener();
this.createImgTime = null;
if (navigationDiv) navigationDiv[0].style.display = "block";
}
},
},
destroyed() {
this.removeListener();
},
methods: {
addScale() {
let barWidth = undefined;
let currentScaleUnit = undefined;
var geodesic = new Cesium.EllipsoidGeodesic();
var distances = [
1, 2, 3, 5, 10, 20, 30, 50, 100, 200, 300, 500, 1000, 2000, 3000, 5000,
10000, 20000, 30000, 50000, 100000, 200000, 300000, 500000, 1000000,
2000000, 3000000, 5000000, 10000000, 20000000, 30000000, 50000000,
];
// Find the distance between two pixels at the bottom center of the screen.
let scene = window.selfDefine.viewer.scene;
let width = scene.canvas.clientWidth;
let height = scene.canvas.clientHeight;
let left = scene.camera.getPickRay(
new Cesium.Cartesian2((width / 2) | 0, height - 1)
);
let right = scene.camera.getPickRay(
new Cesium.Cartesian2((1 + width / 2) | 0, height - 1)
);
let globe = scene.globe;
let leftPosition = globe.pick(left, scene);
let rightPosition = globe.pick(right, scene);
if (!Cesium.defined(leftPosition) || !Cesium.defined(rightPosition)) {
barWidth = undefined;
currentScaleUnit = undefined;
return;
}
let leftCartographic =
globe.ellipsoid.cartesianToCartographic(leftPosition);
let rightCartographic =
globe.ellipsoid.cartesianToCartographic(rightPosition);
geodesic.setEndPoints(leftCartographic, rightCartographic);
let pixelDistance = geodesic.surfaceDistance;
// Find the first distance that makes the scale bar less than 100 pixels.
let maxBarWidth = 100;
let distance;
for (
let i = distances.length - 1;
!Cesium.defined(distance) && i >= 0;
--i
) {
if (distances[i] / pixelDistance < maxBarWidth) {
distance = distances[i];
}
}
if (Cesium.defined(distance)) {
currentScaleUnit = distance >= 1000 ? "km" : "m";
barWidth =
distance >= 1000 ? (distance / 1000).toString() : distance.toString();
} else {
barWidth = undefined;
currentScaleUnit = undefined;
}
drawScaleTwo(barWidth, currentScaleUnit);
},
addGrid() {
const cesiumExtent =
window.selfDefine.viewer.camera.computeViewRectangle();
const params = {};
params.xmax = Cesium.Math.toDegrees(cesiumExtent.east);
params.ymax = Cesium.Math.toDegrees(cesiumExtent.north);
params.xmin = Cesium.Math.toDegrees(cesiumExtent.west);
params.ymin = Cesium.Math.toDegrees(cesiumExtent.south);
drawGrid(6, 6, "cesiumView", [
params.xmax,
params.ymax,
params.xmin,
params.ymin,
]);
},
getcurrentdomwidth(dom) {
const domObj = document.getElementById(dom);
const clientWidth = domObj.clientWidth;
const clientHeight = domObj.clientHeight;
const offsetWidth = domObj.offsetWidth;
const offsetHeight = domObj.offsetHeight;
const clientLeft = parseFloat(
getComputedStyle(domObj).getPropertyValue("padding-left")
);
const clientTop = parseFloat(
getComputedStyle(domObj).getPropertyValue("padding-top")
);
return {
w: clientWidth,
h: clientHeight,
concentW: offsetWidth,
concentH: offsetHeight,
paddingL: clientLeft,
paddingT: clientTop,
};
},
DegreesCoverttoDuFenMiao(degrees) {
let du = degrees.split(".")[0];
let fen = ("0." + degrees.split(".")[1]) * 60 + "";
let miao = (("0." + fen.split(".")[1]) * 60).toFixed(0);
return du + "°" + fen.split(".")[0] + "" + miao + "″";
},
removeListener() {
window.selfDefine.viewer.scene.postRender.removeEventListener(
this.addScale
);
window.selfDefine.viewer.scene.postRender.removeEventListener(
this.addGrid
);
},
handleStepSampling(newVal) {
this.stepSampling = newVal;
},
handleDepthList(newVal) {
this.depthList = newVal;
},
editDeepSpace() {
this.stepSampling = true;
},
initParam() {
if (this.sampleCldFun) {
this.simpleForm.sampleFun = new Array(
this.sampleFun,
this.sampleCldFun
);
} else {
this.simpleForm.sampleFun = new Array(this.sampleFun);
}
const ssf = Number(this.simpleForm.sampleFun[0]);
if (
this.simpleForm.sampleFun.length >= 1 &&
ssf === 2 &&
Number(this.simpleForm.sampleFun[1]) === 0
) {
this.isDeepSpace = true;
} else {
this.isDeepSpace = false;
}
},
pickValue() {
cu.handleClick();
},
changeSampleFun(sfVal) {
//保存样本抽样方法
if (Array.isArray(sfVal)) {
const ssf = Number(sfVal[0]);
this.$store.commit("setSampleFun", sfVal.length === 0 ? null : ssf);
if (sfVal.length >= 1 && ssf === 2 && Number(sfVal[1]) === 0) {
this.isDeepSpace = true;
} else {
this.isDeepSpace = false;
}
}
},
samplesCk() {
const self = this;
if (self.simpleForm.sampleFun[0] === "") {
self.$message.error("请选择抽样方法");
return false;
}
const ssf = self.simpleForm.sampleFun,
st = self.simpleDataTotal,
ssn = self.simpleForm.sampleNum;
if (ssn == "") {
this.$message.error("请选择抽样个数");
this.getSplData();
return false;
}
if (ssn > st) {
this.$message.error("抽样数不可大于总样本数量");
return false;
}
if (ssn < 0) {
this.$message.error("样本个数不可为负数");
return false;
}
if (Number(ssf[0]) === 2) {
const stepSampParams = self.$refs.sampleSettingPanel;
const hierarchyVal = ssf[1];
if (hierarchyVal === "" || hierarchyVal === undefined) {
self.stepSampling = true;
return false;
}
const ssForm = new FormData();
ssForm.append("samplesList", JSON.stringify(self.allSampleData));
ssForm.append("stepType", Number(hierarchyVal));
ssForm.append("orderID", self.orderId);
if (hierarchyVal === "0") {
const depthList = this.depthList;
ssForm.append("condition", JSON.stringify(depthList));
} else if (hierarchyVal === "2") {
const jsonContent = JSON.parse(stepSampParams.jsonContent);
const jg = jsonContent.geometries;
const newPolygon = [];
for (let i in jg) {
const jsonContentWKT = WKT.convert(jg[i]);
newPolygon.push({ coordinates: jsonContentWKT });
}
ssForm.append("condition", JSON.stringify(newPolygon));
}
ssForm.append("splCount", ssn);
getSamplesByLayer(ssForm).then((res) => {
if (res.length === 0 || res == []) {
self.multipleSelection = self.simpleData = [];
cu.removePoint();
self.$message.error("当前分层设置返回列表为空");
return false;
} else {
const dl = [];
for (let i in res) {
const ri = res[i];
for (let j in ri) {
ri[j]["hierarchicalIdentification"] = i;
dl.push(ri[j]);
}
}
self.multipleSelection = self.simpleData = dl;
self.$refs.multipleTable.toggleAllSelection();
cu.removePoint();
for (let i in dl) {
cu.addPoint(dl[i].lng, dl[i].lat, 10);
}
}
});
} else {
const spFrom = new FormData();
spFrom.append("sampleFun", Number(ssf[0])); //抽样方法
spFrom.append("minNum", 0);
spFrom.append("MaxNum", st - 1); //样本总数
spFrom.append("splCount", ssn); //抽样个数
getSampleData(spFrom).then((res) => {
const dl = [];
for (const i in res) {
let sri = self.allSampleData[res[i]];
sri["hierarchicalIdentification"] = "0";
dl.push(sri);
}
self.multipleSelection = self.simpleData = dl;
self.$refs.multipleTable.toggleAllSelection();
cu.removePoint();
for (let i in dl) {
cu.addPoint(dl[i].lng, dl[i].lat, 10);
}
});
}
},
tableRowClassName({ rowIndex }) {
if ((rowIndex + 1) % 2 !== 0) {
return "background:#F5F7FA;text-align:center";
} else {
return "background:#FFFFFF;text-align:center";
}
},
headerRowClass() {
return "background: #E4E9F1;text-align:center";
},
handleSelectionChange(val) {
cu.removePoint();
if (val.length !== 0) {
for (let i in val) {
cu.addPoint(val[i].lng, val[i].lat, 10);
}
}
this.multipleSelection = val;
},
getSplData() {
getSamplesList(this.orderId).then((res) => {
if (res.code == 200) {
let rd = res.data.list;
if (rd.length > 0) {
for (const i in rd) {
// 添加默认样本分层标识
rd[i]["hierarchicalIdentification"] = "0";
}
this.multipleSelection = this.allSampleData = this.simpleData = rd;
this.loading = false;
this.$refs.multipleTable.toggleAllSelection();
let min = Number.MAX_SAFE_INTEGER;
let max = Number.MIN_SAFE_INTEGER;
this.$store.commit("setAltRange", null);
this.allSampleData.forEach((k, v) => {
k.dataTime = this.formatDatetime(k.dataTime);
const xqsmParam = JSON.parse(k.paramStr);
if (xqsmParam.alt) {
min = min > xqsmParam.alt ? xqsmParam.alt : min;
max = max < xqsmParam.alt ? xqsmParam.alt : max;
} else {
(min = 0), (max = 0);
}
});
if (this.allSampleData.length > 0) {
this.$store.commit("setAltRange", min + "," + (max + 1));
}
this.simpleDataTotal = this.simpleForm.total = rd.length;
this.smLabel = this.simpleData[0].productSubTypeName;
}
}
});
},
deleteSelected(index, simpleData) {
this.$confirm(`确定删除该样本?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(async () => {
simpleData.splice(index, 1);
});
},
},
computed: {
globalSampleFun: function () {
return this.$store.state.sampleFun;
},
globalPixelFun: function () {
return this.$store.state.pixelFun;
},
},
};
</script>
<style scoped lang="less">
.soilMositure {
margin-top: 10px;
margin-bottom: 10px;
}
.smBodyLeft {
width: 56%;
height: 570px;
float: left;
margin-right: 4px;
}
.smBodyRight {
width: calc(44% - 4px);
height: 570px;
background-color: white;
float: left;
margin-bottom: 10px;
}
.smps {
height: 570px;
background-color: white;
margin-bottom: 5px;
}
/deep/.smps .el-form-item {
margin-left: 15px;
margin-bottom: 10px;
}
/deep/.smps .el-table th > .cell {
font-size: 15px;
}
/deep/.smps .el-table .cell {
font-size: 13px;
}
.block .pagination-container {
padding: 0px;
margin-top: 6px;
text-align: center;
}
.pixelDeal {
height: 165px;
background-color: white;
}
/deep/.pixelDeal .el-form-item {
margin-left: 15px;
}
.cardsp {
display: block;
margin-left: 17px;
font-size: 15px;
color: #606266;
line-height: 40px;
}
.sceneShowContent {
height: calc(100% - 55px);
padding: 5px;
.topContent {
height: 30px;
width: 100%;
text-align: center;
line-height: 30px;
.mapTitle {
font-size: 22px;
font-weight: bold;
}
}
#mapContent {
height: calc(100% - 100px);
position: relative;
padding-left: 70px;
padding-top: 30px;
#grid {
position: absolute;
left: 0;
right: 0;
top: 0;
left: 0;
}
.compass {
width: 50px;
height: 50px;
position: absolute;
top: 10px;
right: 20px;
z-index: 2;
}
#scaleBar {
width: 300px;
height: 40px;
position: absolute;
bottom: 10px;
left: 30px;
z-index: 2;
}
}
#cesiumContent {
height: 100%;
position: relative;
padding-top: 5px;
padding-left: 5px;
}
#cesiumView {
width: calc(100% - 10px);
height: calc(100% - 10px);
overflow: hidden;
position: relative;
border: 2px solid black;
}
.bottomCont {
height: 60px;
text-align: left;
width: fit-content;
transform: translateX(-100%);
margin-left: 100%;
white-space: nowrap;
}
}
.onBorder {
border: 1px solid;
}
.box1 {
height: 40px;
line-height: 40px;
border-bottom: 1px solid rgb(205, 205, 205, 0.5);
}
.sp1 {
display: inline-block;
width: 7px;
height: 26px;
background-color: #354595;
vertical-align: top;
margin-left: 20px;
margin-top: 8px;
}
.sp2 {
margin-left: 10px;
font-size: 20px;
font-weight: 700;
color: #354595;
vertical-align: top;
}
.sp3 {
position: relative;
top: -13px;
margin-left: 10px;
}
// 分层抽样弹出框设置
/deep/.sampleFunParam .el-upload-dragger .el-icon-upload {
margin: 0;
line-height: 30px;
font-size: 20px;
color: black;
}
.sampleFunParam .upload-demo {
display: inline-block;
}
/deep/.sampleFunParam .el-upload-dragger {
width: 150px;
height: 35px;
margin-left: 15px;
margin-top: 20px;
border: 1px solid #d9d9d9;
}
/deep/.sampleFunParam .el-dialog__body {
padding: 20px 10px;
text-align: center;
}
.edit-btn {
margin-left: 15px;
}
</style>