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

815 lines
25 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="qualitative">
<div class="featureMap">
<div class="box1">
<span class="sp1"></span><span class="sp2">{{
productSubType == 39 ? "地表覆盖类型表" : "植被物候类型表"
}}</span>
</div>
<el-table ref="featureMapMultipleTable" :data="featureMapData" tooltip-effect="dark"
:header-cell-style="headerRowClass" style="width: 98%; margin-left: 1%; margin-top: 15px" :stripe="true"
:cell-style="tableRowClassName" height="230">
<el-table-column label="序号" type="index" width="70">
</el-table-column>
<el-table-column prop="coverName" :label="productSubType == 39 ? '地物类型名称' : '物候类型名称'" show-overflow-tooltip>
</el-table-column>
<el-table-column prop="typeNameKg" label="空基类型名称" show-overflow-tooltip v-if="false">
<template slot-scope="scope">
<el-select v-model="scope.row.typeNameKg" placeholder="请选择" @change="selectRfName(scope.row)">
<el-option v-for="item in rfNameOpt" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="用户类型实际值">
<template slot-scope="scope">{{ scope.row.coverId }}</template>
</el-table-column>
<el-table-column label="空基代码实际值">
<template slot-scope="scope">{{ scope.row.imageValue }}</template>
</el-table-column>
</el-table>
</div>
<div class="qualiteSample">
<div class="qsLeft">
<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="400"
size="medium">
<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>
</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 prop="coverName" label="类别" show-overflow-tooltip sortable>
<template slot-scope="scope">{{
scope.row.paramStr | getCoverName
}}</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"><i class="el-icon-delete"
@click="deleteSelected(scope.$index, simpleData)"></i></template>
</el-table-column>
</el-table>
</div>
</div>
<div class="pixelDeal" v-if="false">
<div class="box1">
<span class="sp1"></span><span class="sp2">像元级处理模型设置</span>
</div>
<div>
<span class="cardsp">目标分辨率:{{ pixelNum }}</span>
<el-form :inline="true" :model="pixelFormData" class="demo-form-inline">
<el-form-item label="像元级处理模型:">
<el-select size="mini" v-model="pixelFormData.pixelDealFun" placeholder="选择像元级处理方法" :disabled="pdShow">
<el-option label="" value=""></el-option>
<el-option label="均值法" value="1"></el-option>
<el-option label="最邻近法" value="6"></el-option>
<el-option label="克里格法" value="7"></el-option>
<el-option label="块克里格法" value="9"></el-option>
<el-option label="MSN法" value="10"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit"></el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
<div class="qsRight">
<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">待检验产品图</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 id="sceneShowContent" @click="pickValue" style="overflow: hidden; position: relative"></div> -->
</div>
</div>
<SampleSetting :stepSampling="stepSampling" @handleStepSampling="handleStepSampling"
@handleDepthList="handleDepthList" :sampleCldFun="sampleCldFun" ref="sampleSettingPanel"></SampleSetting>
</div>
</template>
<script>
// import {
// getCoverTypes,
// getSampleData,
// getOrderSamples,
// getSamplesByLayer,
// } from "@/api/pendingOrder";
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,
},
featureMapData: {
require: true,
},
checkRealityWait: {
require: true,
}
},
filters: {
getCoverName(paramStr) {
return JSON.parse(paramStr).covernm;
},
},
data() {
return {
// featureMapData: [],
rfNameOpt: [],
simpleForm: {
sampleFun: "",
sampleNum: "",
},
simpleData: [],
loading: true,
allSampleData: [],
simpleDataTotal: 0,
multipleSelection: [],
pixelFormData: {
pixelDealFun: "",
},
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() {
if (this.productSubType === 39) {
this.rfNameOpt = this.configration.groTypeName;
} else if (this.productSubType === 47) {
this.rfNameOpt = this.configration.vegetationPhenologyGroTypeName;
}
this.funcOpt = this.configration.funcOpt;
// this.getCoverType();
this.getSqlData();
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) {
// console.log('handleDepthList', newVal)
this.depthList = newVal;
},
editDeepSpace() {
this.stepSampling = true;
},
initParam() {
if (this.pixelFun !== "") this.pdShow = true;
this.pixelFormData.pixelDealFun = this.pixelFun;
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;
}
// this.stepSampling = this.sampleFun == "1" && this?.sampleCldFun == "0";
},
onSubmit() { },
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) {
const alt = JSON.parse(val[i].paramStr).alt;
cu.addPoint(val[i].lng, val[i].lat, alt !== "null" ? alt : 10);
}
}
this.multipleSelection = val;
},
selectRfName(row) {
const typeNameMap = {
城市: "01",
水体: "02",
森林: "03",
灌木地: "20",
草地: "10",
水域: "60",
山地: "80",
出芽期: "1",
分蘖期: "2",
越冬期: "3",
返青期: "4",
起身期: "5",
拔节期: "6",
孕穗期: "7",
抽穗期: "8",
扬花期: "9",
灌浆期: "10",
成熟期: "11",
};
row.typeIdKg = typeNameMap[row.typeNameKg];
},
getRealVal(name) {
const typeNameMap = {
城市: "01",
水体: "02",
森林: "03",
灌木地: "20",
草地: "10",
水域: "60",
山地: "80",
出芽期: "1",
分蘖期: "2",
越冬期: "3",
返青期: "4",
起身期: "5",
拔节期: "6",
孕穗期: "7",
抽穗期: "8",
扬花期: "9",
灌浆期: "10",
成熟期: "11",
};
return typeNameMap[name];
},
getCoverType() {
getCoverTypes(this.orderId).then((res) => {
if (res.msg === "操作成功" && res?.data) {
const rd = res.data;
if (rd.length > 0) {
for (let i = 0; i < rd.length; i++) {
rd[i].typeNameKg = rd[i].typeName;
rd[i].typeIdKg = this.getRealVal(rd[i].typeName);
}
}
this.featureMapData = rd;
}
});
},
getSqlData() {
getSamplesList(this.orderId).then((res) => {
// console.log("111111111", res);
if (res.code == 200) {
this.multipleSelection =
this.allSampleData =
this.simpleData =
res.data.list;
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);
min = min > k.alt ? k.alt : min;
max = max < k.alt ? k.alt : max;
});
if (this.allSampleData.length > 0) {
this.$store.commit("setAltRange", min + "," + (max + 1));
}
this.simpleDataTotal = res.data.list.length;
}
});
},
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.getSqlData();
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(this.allSampleData));
ssForm.append("stepType", Number(hierarchyVal));
ssForm.append("orderID", this.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();
this.$message.error("当前分层设置返回列表为空");
return false;
} else {
const dl = [];
for (let i in res) {
const ri = res[i];
for (let j in ri) {
dl.push(ri[j]);
}
}
self.multipleSelection = self.simpleData = dl;
self.$refs.multipleTable.toggleAllSelection();
cu.removePoint();
for (let i in dl) {
const alt = JSON.parse(dl[i].paramStr).alt;
cu.addPoint(dl[i].lng, dl[i].lat, alt !== "null" ? alt : 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) {
dl.push(self.allSampleData[res[i]]);
}
self.multipleSelection = self.simpleData = dl;
self.$refs.multipleTable.toggleAllSelection();
cu.removePoint();
for (let i in dl) {
const alt = JSON.parse(dl[i].paramStr).alt;
cu.addPoint(dl[i].lng, dl[i].lat, alt !== "null" ? alt : 10);
}
});
}
},
deleteSelected(index, simpleData) {
simpleData.splice(index, 1);
},
pickValue() {
cu.handleClick();
},
},
};
</script>
<style scoped lang="less">
.featureMap {
width: 100%;
height: 300px;
background-color: white;
margin-top: 10px;
}
/deep/.featureMap .el-select .el-input__inner {
height: 35px;
}
.qualiteSample {
margin-top: 10px;
margin-bottom: 10px;
}
.qsLeft {
width: 56%;
height: 500px;
float: left;
margin-right: 4px;
}
.qsRight {
width: calc(44% - 4px);
height: 500px;
background-color: white;
float: left;
margin-bottom: 10px;
}
.smps {
height: 500px;
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;
// }
.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 {
// margin: 10px;
// height: calc(100% - 60px);
// background-color: rgb(110, 110, 207);
// }
.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;
}
// 分层抽样弹出框设置
/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>