updated
This commit is contained in:
commit
7b8dfb496f
|
|
@ -33,6 +33,15 @@ module.exports = {
|
||||||
'^/api': '/ds1'
|
'^/api': '/ds1'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
context: '/api/report/ship/total.htm',
|
||||||
|
target: 'https://weixin.bdsmart.cn',
|
||||||
|
changeOrigin: true,
|
||||||
|
secure: true,
|
||||||
|
pathRewrite: {
|
||||||
|
'^/api': '/ds1'
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
context: '/api',
|
context: '/api',
|
||||||
target: 'http://test.gopmas.com/ds', // 测试环境
|
target: 'http://test.gopmas.com/ds', // 测试环境
|
||||||
|
|
|
||||||
|
|
@ -1783,6 +1783,12 @@ header{
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mapboxgl-popup-content {
|
||||||
|
background-color: rgba(255, 255, 255, 0.9) !important;
|
||||||
|
padding-bottom: 5px !important;
|
||||||
|
border-radius: 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
.popup-table {
|
.popup-table {
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
font-family: 'Microsoft YaHei';
|
font-family: 'Microsoft YaHei';
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ export class ColorGenerator {
|
||||||
positiveColor = '#1a9850'
|
positiveColor = '#1a9850'
|
||||||
) {
|
) {
|
||||||
const colors = [];
|
const colors = [];
|
||||||
const midPoint = Math.floor(count / 2);
|
const midPoint = Math.floor(count + 1 / 2);
|
||||||
|
|
||||||
// 负值部分
|
// 负值部分
|
||||||
const negRGB = this.parseHexColor(negativeColor);
|
const negRGB = this.parseHexColor(negativeColor);
|
||||||
|
|
|
||||||
|
|
@ -86,11 +86,11 @@ export function initMapbox(mapId, options = {}) {
|
||||||
map.on('load', () => {
|
map.on('load', () => {
|
||||||
// 加载海岸线
|
// 加载海岸线
|
||||||
if (options.coastlineOn || false)
|
if (options.coastlineOn || false)
|
||||||
loadVectorLayer("GSHHS_f_L1", ["line"], ["#5c71c3"], "visible", mapId, 'ougp');
|
loadVectorLayer({ layerId: "GSHHS_f_L1", features: ["line"], colors: ["#5c71c3"], visibility: "visible", mapId, workspace: 'ougp' });
|
||||||
// 加载等深线
|
// 加载等深线
|
||||||
if (options.contourOn || false) {
|
if (options.contourOn || false) {
|
||||||
loadVectorLayer("contour-4500m", ["line"], ["#FEFEFE"], "visible", mapId, 'ougp');
|
loadVectorLayer({ layerId: "contour-4500m", features: ["line"], colors: ["#FEFEFE"], visibility: "visible", mapId, workspace: 'ougp' });
|
||||||
loadVectorLayer("contour-6000m", ["line"], ["#FEFEFE"], "visible", mapId, 'ougp');
|
loadVectorLayer({ layerId: "contour-6000m", features: ["line"], colors: ["#FEFEFE"], visibility: "visible", mapId, workspace: 'ougp' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,45 @@ import { regInfo } from '@/api/dataSearch'
|
||||||
|
|
||||||
let sourceLayer = undefined;
|
let sourceLayer = undefined;
|
||||||
let clickedLineIds = [];
|
let clickedLineIds = [];
|
||||||
// 单例 Popup,用于确保地图上只有一个弹框实例
|
|
||||||
let sharedPopup = null;
|
|
||||||
|
|
||||||
export function loadVectorLayer(layerId, features = ["line", "symbol"], colors = ["#FEFEFE", "#FF0000"], visibility = "visible", mapId = "homeMap", workspace = 'dsds', textField = "name") {
|
// 存储可复用的每个地图对象的唯一 Popup 实例(key 为 mapId),以避免频繁创建/销毁 Popup 导致的性能问题和潜在内存泄漏
|
||||||
|
let sharedPopup = {};
|
||||||
|
// 存储上一条点击的线
|
||||||
|
let lastLineId;
|
||||||
|
|
||||||
|
// 默认的线宽表达式
|
||||||
|
export let lineWidthExpression = [
|
||||||
|
"case",
|
||||||
|
["boolean", ["feature-state", "hover"], false],
|
||||||
|
4,
|
||||||
|
["boolean", ["feature-state", "click"], false],
|
||||||
|
2,
|
||||||
|
1.8
|
||||||
|
];
|
||||||
|
|
||||||
|
export function setMapLayoutProperty(mapId, visibility = "none") {
|
||||||
|
// 设置所有图层的显示/隐藏状态(根据图层类型或名称过滤底图图层,避免误操作)
|
||||||
|
const layers = Vue.config.maps[mapId].getStyle().layers;
|
||||||
|
layers.forEach(layer => {
|
||||||
|
// 跳过底图
|
||||||
|
if (layer.id !== '影像地图' && layer.type !== 'raster') {
|
||||||
|
Vue.config.maps[mapId].setLayoutProperty(layer.id, 'visibility', visibility);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setMapPaintProperty({ mapId, property, value }) {
|
||||||
|
const layers = Vue.config.maps[mapId].getStyle().layers;
|
||||||
|
layers.forEach(layer => {
|
||||||
|
// 跳过底图和非测线图层
|
||||||
|
if (layer.id !== '影像地图' && layer.type !== 'raster' && layer.id.endsWith("-line")) {
|
||||||
|
Vue.config.maps[mapId].setPaintProperty(layer.id, property, lineWidthExpression);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Vue.config.maps[mapId].setPaintProperty(layerId, "line-width", 14);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loadVectorLayer({ layerId, features = ["line", "symbol"], colors = ["#FEFEFE", "#FF0000"], visibility = "visible", mapId = "homeMap", workspace = 'dsds', textField = "name", callbackOnClick }) {
|
||||||
// 添加数据源
|
// 添加数据源
|
||||||
const sourceId = `vector-${layerId}`;
|
const sourceId = `vector-${layerId}`;
|
||||||
let source = Vue.config.maps[mapId].getSource(sourceId);
|
let source = Vue.config.maps[mapId].getSource(sourceId);
|
||||||
|
|
@ -40,11 +75,11 @@ export function loadVectorLayer(layerId, features = ["line", "symbol"], colors =
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
features.forEach((feature) => {
|
features.forEach((feature) => {
|
||||||
loadVectorFeature(layerId, feature, colors[i++], visibility, mapId, textField);
|
loadVectorFeature({ layerId, feature, color: colors[i++], visibility, mapId, textField, callbackOnClick });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadVectorFeature(layerId, feature, color, visibility, mapId, textField = "name") {
|
export async function loadVectorFeature({ layerId, feature, color, visibility, mapId, textField = "name", callbackOnClick }) {
|
||||||
let sourceId = `vector-${layerId}`;
|
let sourceId = `vector-${layerId}`;
|
||||||
// symbol
|
// symbol
|
||||||
// Slot 是 Mapbox 样式规范中的一个概念,它定义了图层在渲染过程中的位置和顺序。
|
// Slot 是 Mapbox 样式规范中的一个概念,它定义了图层在渲染过程中的位置和顺序。
|
||||||
|
|
@ -127,15 +162,23 @@ export async function loadVectorFeature(layerId, feature, color, visibility, map
|
||||||
// 'slot': 'foreground'
|
// 'slot': 'foreground'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// 图层已存在则设置为可见
|
||||||
|
Vue.config.maps[mapId].setLayoutProperty(`${sourceId}-${feature}`, "visibility", "visible");
|
||||||
|
}
|
||||||
|
|
||||||
// 点击可交互的图层,显示相关信息
|
// 点击可交互的图层,显示相关信息
|
||||||
await setHighlight(`${sourceId}-${feature}`, sourceId, mapId);
|
await setHighlight(`${sourceId}-${feature}`, sourceId, mapId);
|
||||||
changeCursor(`${sourceId}-${feature}`, mapId);
|
changeCursor(`${sourceId}-${feature}`, mapId);
|
||||||
|
|
||||||
if (layerId.includes("sample_line"))
|
if (layerId.includes("sample_line"))
|
||||||
await showSampleLineInfo(`${sourceId}-${feature}`, mapId);
|
await showSampleLineInfo(`${sourceId}-${feature}`, mapId, callbackOnClick);
|
||||||
if (layerId.includes("sample_station"))
|
if (layerId.includes("sample_station"))
|
||||||
await showSampleStationInfo(`${sourceId}-${feature}`, mapId);
|
await showSampleStationInfo(`${sourceId}-${feature}`, mapId, callbackOnClick);
|
||||||
|
else if (sourceId.includes("-SY") || sourceId.includes("-FDZ")) {
|
||||||
|
await showDiveInfo(`${sourceId}-${feature}`, mapId);
|
||||||
|
console.log(mapId, `${sourceId}-${feature}`);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
await showTrackInfo(`${sourceId}-${feature}`, mapId);
|
await showTrackInfo(`${sourceId}-${feature}`, mapId);
|
||||||
|
|
||||||
|
|
@ -145,8 +188,10 @@ export async function loadVectorFeature(layerId, feature, color, visibility, map
|
||||||
export function setHighlight(layerId, sourceId, mapId = "homeMap") {
|
export function setHighlight(layerId, sourceId, mapId = "homeMap") {
|
||||||
let hoveredLineId = null;
|
let hoveredLineId = null;
|
||||||
let clickedLineId = null;
|
let clickedLineId = null;
|
||||||
Vue.config.maps[mapId].on('click', layerId, (e) => {
|
Vue.config.maps[mapId].on('click', layerId, async (e) => {
|
||||||
if (!e.features || e.features.length <= 0)
|
sourceLayer = e.features[0].sourceLayer;
|
||||||
|
// 排除没有 sourceLayer 的情况(如点击事件中 features 可能来自多个图层,某些图层缺乏 sourceLayer 属性会导致后续 setFeatureState 报错)
|
||||||
|
if (!sourceLayer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// // 查询点击点周围的所有要素(使用边界框)
|
// // 查询点击点周围的所有要素(使用边界框)
|
||||||
|
|
@ -161,9 +206,6 @@ export function setHighlight(layerId, sourceId, mapId = "homeMap") {
|
||||||
// // const featuresByLayer = groupFeaturesByLayer(allFeatures);
|
// // const featuresByLayer = groupFeaturesByLayer(allFeatures);
|
||||||
// // console.log('点击位置附近的所有要素:', featuresByLayer);
|
// // console.log('点击位置附近的所有要素:', featuresByLayer);
|
||||||
|
|
||||||
// console.log(e.features.length, e.features);
|
|
||||||
// console.log("1 e: ", e);
|
|
||||||
|
|
||||||
let feature = e.features[0];
|
let feature = e.features[0];
|
||||||
if (e.features.length > 1 && e.options)
|
if (e.features.length > 1 && e.options)
|
||||||
feature = e.features.filter(f => f.properties.sample_name == e.options.sample_name)[0];
|
feature = e.features.filter(f => f.properties.sample_name == e.options.sample_name)[0];
|
||||||
|
|
@ -188,24 +230,21 @@ export function setHighlight(layerId, sourceId, mapId = "homeMap") {
|
||||||
clickedLineIds = clickedLineIds.filter((item) => item !== clickedLineId);
|
clickedLineIds = clickedLineIds.filter((item) => item !== clickedLineId);
|
||||||
} else {
|
} else {
|
||||||
Vue.config.maps[mapId].setFeatureState({ source: sourceId, sourceLayer: sourceLayer, id: clickedLineId }, { click: true });
|
Vue.config.maps[mapId].setFeatureState({ source: sourceId, sourceLayer: sourceLayer, id: clickedLineId }, { click: true });
|
||||||
// 显示信息框
|
|
||||||
// if (sourceId === 'GMSL Cable Data')
|
|
||||||
// document.getElementById("cable-overlay")!.style.display = 'block';
|
|
||||||
// 单击时加入选择列表(用于单击 ESC 键时取消选择状态)
|
// 单击时加入选择列表(用于单击 ESC 键时取消选择状态)
|
||||||
clickedLineIds.push(clickedLineId);
|
clickedLineIds.push(clickedLineId);
|
||||||
// document.removeEventListener("keydown", removeHighlight, true);
|
// document.removeEventListener("keydown", removeHighlight, true);
|
||||||
document.addEventListener("keydown", (e) => {
|
// document.addEventListener("keydown", (e) => {
|
||||||
removeHighlight(e, sourceId);
|
// removeHighlight(e, sourceId);
|
||||||
}, { once: true }); // once:一个布尔值,表示 listener 在添加之后最多只调用一次。如果为 true,listener 会在其被调用之后自动移除。
|
// }, { once: true }); // once:一个布尔值,表示 listener 在添加之后最多只调用一次。如果为 true,listener 会在其被调用之后自动移除。
|
||||||
// }, true);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// When the user moves their mouse over the state-fill layer, we'll update the feature state for the feature under the mouse.
|
// When the user moves their mouse over the state-fill layer, we'll update the feature state for the feature under the mouse.
|
||||||
Vue.config.maps[mapId].on('mousemove', layerId, (e) => {
|
Vue.config.maps[mapId].on('mousemove', layerId, (e) => {
|
||||||
if (e.features.length <= 0)
|
|
||||||
return;
|
|
||||||
sourceLayer = e.features[0].sourceLayer;
|
sourceLayer = e.features[0].sourceLayer;
|
||||||
|
// 排除没有 sourceLayer 的情况(如点击事件中 features 可能来自多个图层,某些图层缺乏 sourceLayer 属性会导致后续 setFeatureState 报错)
|
||||||
|
if (!sourceLayer)
|
||||||
|
return;
|
||||||
if (hoveredLineId) {
|
if (hoveredLineId) {
|
||||||
Vue.config.maps[mapId].setFeatureState(
|
Vue.config.maps[mapId].setFeatureState(
|
||||||
{ source: sourceId, sourceLayer: sourceLayer, id: hoveredLineId },
|
{ source: sourceId, sourceLayer: sourceLayer, id: hoveredLineId },
|
||||||
|
|
@ -231,6 +270,41 @@ export function setHighlight(layerId, sourceId, mapId = "homeMap") {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function showUnitReport(mapId, unit, coordinate, callbackOnClose = null) {
|
||||||
|
const result = await (await fetch(`${Vue.config.baseUrl}/ds/report/unit/total.htm?unit=${unit}`)).json();
|
||||||
|
const unitReports = result.array || [];
|
||||||
|
if (!unitReports.length) {
|
||||||
|
alert("未查询到相关单位的统计信息");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const description = `
|
||||||
|
<table class="popup-table" style="min-width:280px;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">单位参航信息</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">单位名称: <b>${unitReports[0].unit_name}</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>参航次数: <b>${unitReports[0].voyage_total || "/"}</b></td>
|
||||||
|
<td>参航天数: <b>${unitReports[0].voyage_days || "/"}</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>参航人数: <b>${unitReports[0].member_total || "/"}</b></td>
|
||||||
|
<td>下潜次数: <b>${unitReports[0].drving_total || "/"}</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>首潜人数: <b>${unitReports[0].f_drving_total || "/"}</b></td>
|
||||||
|
<td>首次参航人数: <b>${unitReports[0].f_voyage_total || "/"}</b></td>
|
||||||
|
</tr>
|
||||||
|
</table>`;
|
||||||
|
|
||||||
|
showPopupDetails({ mapId, coordinate, description, maxWidth: "300px", callbackOnClose: callbackOnClose });
|
||||||
|
}
|
||||||
|
|
||||||
export function changeCursor(layerId, mapId = "homeMap", cursor = "pointer") {
|
export function changeCursor(layerId, mapId = "homeMap", cursor = "pointer") {
|
||||||
Vue.config.maps[mapId].on("mouseenter", layerId, () => {
|
Vue.config.maps[mapId].on("mouseenter", layerId, () => {
|
||||||
Vue.config.maps[mapId].getCanvas().style.cursor = cursor;
|
Vue.config.maps[mapId].getCanvas().style.cursor = cursor;
|
||||||
|
|
@ -241,14 +315,20 @@ export function changeCursor(layerId, mapId = "homeMap", cursor = "pointer") {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showSampleLineInfo(layerId, mapId = "homeMap") {
|
export function showSampleLineInfo(layerId, mapId = "homeMap", callbackOnClick = null) {
|
||||||
Vue.config.maps[mapId].on("click", layerId, async (e) => {
|
Vue.config.maps[mapId].on("click", layerId, async (e) => {
|
||||||
|
// 在左侧列表中高亮对应项
|
||||||
|
if (callbackOnClick && typeof callbackOnClick === "function") {
|
||||||
|
callbackOnClick(e.features[0]);
|
||||||
|
}
|
||||||
|
|
||||||
// 禁止点击事件穿透 - 判断同一个 event 是否已经触发,用于避免图层内标记点注册的点击事件重复触发(点位分布密集时容易出现)
|
// 禁止点击事件穿透 - 判断同一个 event 是否已经触发,用于避免图层内标记点注册的点击事件重复触发(点位分布密集时容易出现)
|
||||||
if (e.defaultPrevented)
|
if (e.defaultPrevented)
|
||||||
return;
|
return;
|
||||||
// 标记该 event 已触发,禁止点击事件穿透
|
// 标记该 event 已触发,禁止点击事件穿透
|
||||||
if (typeof e.preventDefault === "function")
|
if (typeof e.preventDefault === "function")
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
// console.log("showSampleLineInfo: ", layerId, e.features[0]);
|
||||||
|
|
||||||
const description = `
|
const description = `
|
||||||
<table class="popup-table" style="min-width:380px;">
|
<table class="popup-table" style="min-width:380px;">
|
||||||
|
|
@ -286,12 +366,17 @@ export function showSampleLineInfo(layerId, mapId = "homeMap") {
|
||||||
</tr>
|
</tr>
|
||||||
</table>`;
|
</table>`;
|
||||||
|
|
||||||
showPopupDetails(mapId, e.lngLat, description, "450px");
|
showPopupDetails({ mapId, coordinate: e.lngLat, description, maxWidth: "450px" });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showSampleStationInfo(layerId, mapId = "homeMap") {
|
export function showSampleStationInfo(layerId, mapId = "homeMap", callbackOnClick = null) {
|
||||||
Vue.config.maps[mapId].on("click", layerId, async (e) => {
|
Vue.config.maps[mapId].on("click", layerId, async (e) => {
|
||||||
|
// 在左侧列表中高亮对应项
|
||||||
|
if (callbackOnClick && typeof callbackOnClick === "function") {
|
||||||
|
callbackOnClick(e.features[0]);
|
||||||
|
}
|
||||||
|
|
||||||
// 禁止点击事件穿透 - 判断同一个 event 是否已经触发,用于避免图层内标记点注册的点击事件重复触发(点位分布密集时容易出现)
|
// 禁止点击事件穿透 - 判断同一个 event 是否已经触发,用于避免图层内标记点注册的点击事件重复触发(点位分布密集时容易出现)
|
||||||
if (e.defaultPrevented)
|
if (e.defaultPrevented)
|
||||||
return;
|
return;
|
||||||
|
|
@ -299,9 +384,6 @@ export function showSampleStationInfo(layerId, mapId = "homeMap") {
|
||||||
// if (typeof e.preventDefault === "function")
|
// if (typeof e.preventDefault === "function")
|
||||||
// e.preventDefault();
|
// e.preventDefault();
|
||||||
|
|
||||||
// console.log(e.features.length, e.features);
|
|
||||||
// console.log("2 e: ", e);
|
|
||||||
|
|
||||||
let feature = e.features[0];
|
let feature = e.features[0];
|
||||||
if (e.features.length > 1)
|
if (e.features.length > 1)
|
||||||
feature = e.features.filter(f => f.properties.sample_name == e.options.sample_name)[0];
|
feature = e.features.filter(f => f.properties.sample_name == e.options.sample_name)[0];
|
||||||
|
|
@ -315,7 +397,7 @@ export function showSampleStationInfo(layerId, mapId = "homeMap") {
|
||||||
</thead>
|
</thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td>数据集名称: <b>${feature.properties.dataset_name}</b></td>
|
<td>数据集名称: <b>${feature.properties.dataset_name}</b></td>
|
||||||
<td>数据样品编号: <b>${feature.properties.sample_name}</b></td>
|
<td>样品编号: <b>${feature.properties.sample_name}</b></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>赞助机构: <b>${feature.properties.funding_org}</b></td>
|
<td>赞助机构: <b>${feature.properties.funding_org}</b></td>
|
||||||
|
|
@ -334,10 +416,106 @@ export function showSampleStationInfo(layerId, mapId = "homeMap") {
|
||||||
</tr>
|
</tr>
|
||||||
</table>`;
|
</table>`;
|
||||||
|
|
||||||
showPopupDetails(mapId, feature.geometry.coordinates, description, "450px");
|
showPopupDetails({ mapId, coordinate: feature.geometry.coordinates, description, maxWidth: "450px" });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function showHighlightSampleInfo({ mapId, job_type, sample, layerId, sourceLayerId, callbackOnClick }) {
|
||||||
|
let description = "";
|
||||||
|
let coordinate;
|
||||||
|
if (job_type == "测线作业") {
|
||||||
|
// // 恢复其它测线的线宽
|
||||||
|
// // setMapPaintProperty({ mapId, property: "line-width", value: lineWidthExpression });
|
||||||
|
// // 恢复上一条高亮测线的宽度
|
||||||
|
// Vue.config.maps[mapId].setPaintProperty(lastLineId, "line-width", lineWidthExpression);
|
||||||
|
// // 高亮当前选择的测线
|
||||||
|
// Vue.config.maps[mapId].setPaintProperty(layerId, "line-width", 5);
|
||||||
|
|
||||||
|
// if (lastLineId)
|
||||||
|
// Vue.config.maps[mapId].setFeatureState(
|
||||||
|
// { sourceId: sourceLayerId, id: lastLineId },
|
||||||
|
// { hover: false }
|
||||||
|
// );
|
||||||
|
// Vue.config.maps[mapId].setFeatureState(
|
||||||
|
// { sourceId: sourceLayerId, id: layerId },
|
||||||
|
// { hover: true }
|
||||||
|
// );
|
||||||
|
|
||||||
|
// if (lastLineId)
|
||||||
|
// Vue.config.maps[mapId].setPaintProperty(lastLineId, 'line-color', '#FFFFFF')
|
||||||
|
// Vue.config.maps[mapId].setPaintProperty(layerId, 'line-color', '#FFFF00')
|
||||||
|
// lastLineId = layerId;
|
||||||
|
|
||||||
|
coordinate = [(Number(sample.start_lon) + Number(sample.end_lon)) / 2, (Number(sample.start_lat) + Number(sample.end_lat)) / 2];
|
||||||
|
description = `
|
||||||
|
<table class="popup-table" style="min-width:380px;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">测线信息</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<td>数据集名称: <b>${sample.dataset_name}</b></td>
|
||||||
|
<td>数据样品编号: <b>${sample.sample_name}</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>赞助机构: <b>${sample.funding_org}</b></td>
|
||||||
|
<td>公开期限: <b>${sample.publish_rule}</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>开始经度: <b>${sample.start_lon}°</b></td>
|
||||||
|
<td>结束经度: <b>${sample.end_lon}°</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>开始纬度: <b>${sample.start_lat}°</b></td>
|
||||||
|
<td>结束纬度: <b>${sample.end_lat}°</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>开始时间: <b>${sample.start_time}</b></td>
|
||||||
|
<td>结束时间: <b>${sample.end_time}</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>测线深度: <b>${sample.line_deep}m</b></td>
|
||||||
|
<td>数据状态: <b>${sample.sample_status}</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">备注信息: <b>${sample.sample_remark}</b></td>
|
||||||
|
</tr>
|
||||||
|
</table>`;
|
||||||
|
}
|
||||||
|
else if (job_type == "站位作业") {
|
||||||
|
coordinate = [sample.sampling_lon, sample.sampling_lat];
|
||||||
|
description = `
|
||||||
|
<table class="popup-table" style="min-width:380px;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">站位信息</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<td>数据集名称: <b>${sample.dataset_name}</b></td>
|
||||||
|
<td>样品编号: <b>${sample.sample_name}</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>赞助机构: <b>${sample.funding_org}</b></td>
|
||||||
|
<td>公开期限: <b>${sample.publish_rule}</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>站位经度: <b>${sample.sampling_lon}°</b></td>
|
||||||
|
<td>站位纬度: <b>${sample.sampling_lat}°</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>采样时间: <b>${sample.sampling_time}</b></td>
|
||||||
|
<td>采样深度: <b>${sample.sampling_deep}m</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">备注信息: <b>${sample.sample_remark}</b></td>
|
||||||
|
</tr>
|
||||||
|
</table>`;
|
||||||
|
}
|
||||||
|
showPopupDetails({ mapId, coordinate, description, maxWidth: "450px", callbackOnClose: callbackOnClick });
|
||||||
|
}
|
||||||
|
|
||||||
export function showTrackInfo(layerId, mapId = "homeMap") {
|
export function showTrackInfo(layerId, mapId = "homeMap") {
|
||||||
Vue.config.maps[mapId].on("click", layerId, async (e) => {
|
Vue.config.maps[mapId].on("click", layerId, async (e) => {
|
||||||
// 禁止点击事件穿透 - 判断同一个 event 是否已经触发,用于避免图层内标记点注册的点击事件重复触发(点位分布密集时容易出现)
|
// 禁止点击事件穿透 - 判断同一个 event 是否已经触发,用于避免图层内标记点注册的点击事件重复触发(点位分布密集时容易出现)
|
||||||
|
|
@ -378,12 +556,42 @@ export function showTrackInfo(layerId, mapId = "homeMap") {
|
||||||
</tr>
|
</tr>
|
||||||
</table>`;
|
</table>`;
|
||||||
|
|
||||||
showPopupDetails(mapId, coordinate, description, "420px");
|
showPopupDetails({ coordinate, mapId, description, maxWidth: "420px" });
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showPopupDetails(mapId, coordinate, description, maxWidth = "300px", closeButton = true, closeOnClick = true, options = {}) {
|
export function showDiveInfo(layerId, mapId = "homeMap") {
|
||||||
|
Vue.config.maps[mapId].on("click", layerId, async (e) => {
|
||||||
|
// 禁止点击事件穿透 - 判断同一个 event 是否已经触发,用于避免图层内标记点注册的点击事件重复触发(点位分布密集时容易出现)
|
||||||
|
if (e.defaultPrevented)
|
||||||
|
return;
|
||||||
|
// 标记该 event 已触发,禁止点击事件穿透
|
||||||
|
if (typeof e.preventDefault === "function")
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const feature = e.features[0];
|
||||||
|
let coordinate = e.lngLat;
|
||||||
|
const description = `
|
||||||
|
<table class="popup-table" style="min-width:280px;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">潜次信息</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">潜次编号: <b>${feature.properties.name}</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">created_at: <b>${feature.properties.created_at}</b></td>
|
||||||
|
</tr>
|
||||||
|
</table>`;
|
||||||
|
|
||||||
|
showPopupDetails({ mapId, coordinate, description, maxWidth: "300px" });
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function showPopupDetails({ mapId, coordinate, description, maxWidth = "300px", closeButton = true, closeOnClick = true, options = {}, callbackOnClose }) {
|
||||||
const map = Vue.config.maps[mapId];
|
const map = Vue.config.maps[mapId];
|
||||||
if (!map)
|
if (!map)
|
||||||
return;
|
return;
|
||||||
|
|
@ -391,42 +599,52 @@ export function showPopupDetails(mapId, coordinate, description, maxWidth = "300
|
||||||
const popupOptions = Object.assign({ offset: {}, className: "my-class", closeButton: closeButton, closeOnClick: closeOnClick }, options);
|
const popupOptions = Object.assign({ offset: {}, className: "my-class", closeButton: closeButton, closeOnClick: closeOnClick }, options);
|
||||||
|
|
||||||
// 如果已有共享 popup,复用并更新位置/内容;否则创建新的并绑定 close 事件以便释放引用
|
// 如果已有共享 popup,复用并更新位置/内容;否则创建新的并绑定 close 事件以便释放引用
|
||||||
if (sharedPopup) {
|
if (sharedPopup[mapId]) {
|
||||||
try {
|
try {
|
||||||
sharedPopup.setLngLat(coordinate)
|
sharedPopup[mapId].setLngLat(coordinate)
|
||||||
.setHTML(description)
|
.setHTML(description)
|
||||||
.setOffset(10)
|
.setOffset(10)
|
||||||
.setMaxWidth(maxWidth);
|
.setMaxWidth(maxWidth)
|
||||||
|
.addTo(map);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
console.error("设置 popup 失败:", err);
|
||||||
try {
|
try {
|
||||||
// 万一现有 popup 状态异常,移除并重新创建
|
// 万一现有 popup 状态异常,移除并重新创建
|
||||||
sharedPopup.remove();
|
sharedPopup[mapId].remove();
|
||||||
sharedPopup = null;
|
sharedPopup[mapId] = null;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("移除异常 popup 失败:", e);
|
console.error("移除异常 popup 失败:", e);
|
||||||
}
|
}
|
||||||
sharedPopup = new window.mapboxgl.Popup(popupOptions)
|
sharedPopup[mapId] = new window.mapboxgl.Popup(popupOptions)
|
||||||
.setLngLat(coordinate)
|
.setLngLat(coordinate)
|
||||||
.setHTML(description)
|
.setHTML(description)
|
||||||
.setOffset(10)
|
.setOffset(10)
|
||||||
.setMaxWidth(maxWidth)
|
.setMaxWidth(maxWidth)
|
||||||
.addTo(map);
|
.addTo(map);
|
||||||
sharedPopup.on('close', () => { sharedPopup = null; });
|
sharedPopup[mapId].on('close', () => {
|
||||||
|
// 关闭弹窗时执行回调(如有)
|
||||||
|
if (callbackOnClose && typeof callbackOnClose === "function") {
|
||||||
|
callbackOnClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sharedPopup = new window.mapboxgl.Popup(popupOptions)
|
sharedPopup[mapId] = new window.mapboxgl.Popup(popupOptions)
|
||||||
.setLngLat(coordinate)
|
.setLngLat(coordinate)
|
||||||
.setHTML(description)
|
.setHTML(description)
|
||||||
.setOffset(10)
|
.setOffset(10)
|
||||||
.setMaxWidth(maxWidth)
|
.setMaxWidth(maxWidth)
|
||||||
.addTo(map);
|
.addTo(map);
|
||||||
sharedPopup.on('close', () => { sharedPopup = null; });
|
sharedPopup[mapId].on('close', () => {
|
||||||
|
// 关闭弹窗时执行回调(如有)
|
||||||
|
if (callbackOnClose && typeof callbackOnClose === "function") {
|
||||||
|
callbackOnClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadJsonLineFeature(layerId, color, geojson, mapId) {
|
export async function loadJsonLineFeature(layerId, color, geojson, mapId) {
|
||||||
// console.log("layerId: ",layerId);
|
|
||||||
|
|
||||||
let source = Vue.config.maps[mapId].getSource(layerId);
|
let source = Vue.config.maps[mapId].getSource(layerId);
|
||||||
if (!source) {
|
if (!source) {
|
||||||
Vue.config.maps[mapId].addSource(layerId, {
|
Vue.config.maps[mapId].addSource(layerId, {
|
||||||
|
|
@ -516,13 +734,11 @@ export async function loadJsonPointFeature(layerId, color, geojson, text_field,
|
||||||
export async function highlightFeaturesByProperty(mapId, sourceId, layerId, propertyName = "sample_name", targetValue = "TARGET_VALUE") {
|
export async function highlightFeaturesByProperty(mapId, sourceId, layerId, propertyName = "sample_name", targetValue = "TARGET_VALUE") {
|
||||||
// 清空所有高亮状态(可选)
|
// 清空所有高亮状态(可选)
|
||||||
Vue.config.maps[mapId].querySourceFeatures(sourceId).forEach(f => {
|
Vue.config.maps[mapId].querySourceFeatures(sourceId).forEach(f => {
|
||||||
console.log("AAAAA: ", f);
|
|
||||||
Vue.config.maps[mapId].setFeatureState({ source: sourceId, id: f.id }, { highlight: false });
|
Vue.config.maps[mapId].setFeatureState({ source: sourceId, id: f.id }, { highlight: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
// 标记匹配要素
|
// 标记匹配要素
|
||||||
Vue.config.maps[mapId].querySourceFeatures(sourceId).forEach(f => {
|
Vue.config.maps[mapId].querySourceFeatures(sourceId).forEach(f => {
|
||||||
console.log("BBBBB: ", f);
|
|
||||||
if (f.properties && f.properties[propertyName] === targetValue) {
|
if (f.properties && f.properties[propertyName] === targetValue) {
|
||||||
Vue.config.maps[mapId].setFeatureState({ source: sourceId, id: f.id }, { highlight: true });
|
Vue.config.maps[mapId].setFeatureState({ source: sourceId, id: f.id }, { highlight: true });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,20 +28,24 @@
|
||||||
<div class="left4-sample-wrap" v-if="radio == '数据样品集'">
|
<div class="left4-sample-wrap" v-if="radio == '数据样品集'">
|
||||||
<p class="rule-text">编号规则:航次编号_平台类型_设备类型_数据样品类型</p>
|
<p class="rule-text">编号规则:航次编号_平台类型_设备类型_数据样品类型</p>
|
||||||
<div class="left4">
|
<div class="left4">
|
||||||
<div v-for="(item, index) in dataList" :key="index" :id="item.tsy_id" class="left4_1" >
|
<div v-for="(item, index) in dataList" :key="index" :id="item.tsy_id" class="left4_1">
|
||||||
<div class="left4_top">
|
<div class="left4_top">
|
||||||
<p @click="openList(item, 'list')" style="font-weight: 400;font-size: 14px;cursor: pointer;color: #409eff" >{{ item.dataset_name }} <span class="mileage">{{ item.file_total }}</span></p>
|
<p @click="openList(item, 'list')"
|
||||||
|
style="font-weight: 400;font-size: 14px;cursor: pointer;color: #409eff">{{ item.dataset_name }} <span
|
||||||
|
class="mileage">{{ item.file_total }}</span></p>
|
||||||
<span class="org">{{ item.create_time }}</span>
|
<span class="org">{{ item.create_time }}</span>
|
||||||
</div>
|
</div>
|
||||||
<ul v-show="currenId == item.tsy_id && fold">
|
<ul v-show="currenId == item.tsy_id && fold">
|
||||||
<li :class="sample.tsy_id == currenSample ? 'bg-color' : ''" class="sample" :id="sample.tsy_id"
|
<li :class="sample.tsy_id == currenSample ? 'bg-color' : ''" class="sample" :id="sample.tsy_id"
|
||||||
v-for="(sample, i) in item.sampleArray" :key="i" @click.stop="onSample(sample, item.job_type)">{{ sample.sample_name }}
|
v-for="(sample, i) in item.sampleArray" :key="i" @click.stop="onSample(sample, item.job_type)">{{
|
||||||
|
sample.sample_name }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="left4_list">
|
<div class="left4_list">
|
||||||
<div class="list1">
|
<div class="list1">
|
||||||
<p>航次:</p>
|
<p>航次:</p>
|
||||||
<span class="hover-color" style="color: #409eff" @click="turnDeatilPage(item)">{{ item.voyage_name }}</span>
|
<span class="hover-color" style="color: #409eff" @click="turnDeatilPage(item)">{{ item.voyage_name
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="list1">
|
<div class="list1">
|
||||||
<p>平台类型:</p>
|
<p>平台类型:</p>
|
||||||
|
|
@ -226,13 +230,10 @@ import {
|
||||||
import { getParamsList, getVoyageLine } from '../api/home'
|
import { getParamsList, getVoyageLine } from '../api/home'
|
||||||
import { regInfo } from '@/api/dataSearch'
|
import { regInfo } from '@/api/dataSearch'
|
||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
import {
|
|
||||||
setImageryViewModels
|
|
||||||
} from '@/utils/common'
|
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import { loadVectorLayer, loadJsonLineFeature, loadJsonPointFeature, highlightFeaturesByProperty } from '@/utils/vector-layer-utils'
|
import { setMapLayoutProperty, loadVectorLayer, showHighlightSampleInfo, lineWidthExpression } from '@/utils/vector-layer-utils'
|
||||||
import { ColorGenerator } from '@/utils/color-generator';
|
import { ColorGenerator } from '@/utils/color-generator';
|
||||||
import { initMapbox, handleWheel, initSprites, triggerLayerClick } from "@/utils/mapbox-utils";
|
import { initMapbox, triggerLayerClick } from "@/utils/mapbox-utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Shuju',
|
name: 'Shuju',
|
||||||
|
|
@ -354,8 +355,8 @@ export default {
|
||||||
center: [122, 15],
|
center: [122, 15],
|
||||||
minZoom: 2,
|
minZoom: 2,
|
||||||
maxZoom: 29,
|
maxZoom: 29,
|
||||||
coastlineOn:false,
|
coastlineOn: false,
|
||||||
contourOn:false
|
contourOn: false
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -443,6 +444,9 @@ export default {
|
||||||
FrameSessionId: Cookies.get('JSESSIONID')
|
FrameSessionId: Cookies.get('JSESSIONID')
|
||||||
}
|
}
|
||||||
getDataList(params).then(res => {
|
getDataList(params).then(res => {
|
||||||
|
// 先隐藏所有图层,再根据筛选结果显示对应图层
|
||||||
|
setMapLayoutProperty('dataSearchMap', 'none')
|
||||||
|
|
||||||
const arr = res.page.records
|
const arr = res.page.records
|
||||||
if (this.radio === '航次') {
|
if (this.radio === '航次') {
|
||||||
if (arr.length) {
|
if (arr.length) {
|
||||||
|
|
@ -451,9 +455,8 @@ export default {
|
||||||
arr.forEach(item => {
|
arr.forEach(item => {
|
||||||
item.highlight = false
|
item.highlight = false
|
||||||
item.show = true
|
item.show = true
|
||||||
// this.addSingleLineImg(item.voyage_name, null)
|
|
||||||
// 加载轨迹图层
|
// 加载轨迹图层
|
||||||
loadVectorLayer(item.voyage_name, ["line", "symbol"], [colors[i], colors[i]], "visible", "dataSearchMap", "dsds");
|
loadVectorLayer({ layerId: item.voyage_name, features: ["line", "symbol"], colors: [colors[i], colors[i]], visibility: "visible", mapId: "dataSearchMap", workspace: "dsds" });
|
||||||
i++;
|
i++;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -476,14 +479,6 @@ export default {
|
||||||
},
|
},
|
||||||
// 清除高亮
|
// 清除高亮
|
||||||
clearHighlight(voyageName, i) {
|
clearHighlight(voyageName, i) {
|
||||||
let lineWidthExpression = [
|
|
||||||
"case",
|
|
||||||
["boolean", ["feature-state", "hover"], false],
|
|
||||||
4,
|
|
||||||
["boolean", ["feature-state", "click"], false],
|
|
||||||
2,
|
|
||||||
1.8
|
|
||||||
];
|
|
||||||
Vue.config.maps["dataSearchMap"].setPaintProperty(`vector-${voyageName}-line`, "line-width", lineWidthExpression);
|
Vue.config.maps["dataSearchMap"].setPaintProperty(`vector-${voyageName}-line`, "line-width", lineWidthExpression);
|
||||||
this.dataList[i].highlight = false;
|
this.dataList[i].highlight = false;
|
||||||
},
|
},
|
||||||
|
|
@ -529,11 +524,13 @@ export default {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
const colors = ColorGenerator.generateDivergingColors(arr.length);
|
const colors = ColorGenerator.generateDivergingColors(arr.length);
|
||||||
arr.forEach(item => {
|
arr.forEach(item => {
|
||||||
|
// 加载测线/站位所在航次的轨迹
|
||||||
|
// loadVectorLayer({layerId:item.voyage_name, features:["line", "symbol"], colors:[colors[i], colors[i]], visibility:"visible", mapId:"dataSearchMap", workspace:"dsds"});
|
||||||
// 添加测线/站位图层
|
// 添加测线/站位图层
|
||||||
if (item.job_type == "测线作业") {
|
if (item.job_type == "测线作业") {
|
||||||
loadVectorLayer(`sample_line_${item.dataset_name}`, ["line"], ["#FFFFFF", "#FFFFFF"], "visible", "dataSearchMap", "dsds", "sample_name");
|
loadVectorLayer({ layerId: `sample_line_${item.dataset_name}`, features: ["line"], colors: ["#FFFFFF", "#FFFFFF"], visibility: "visible", mapId: "dataSearchMap", workspace: "dsds", textField: "sample_name", callbackOnClick: this.setHightItem });
|
||||||
} else {
|
} else {
|
||||||
loadVectorLayer(`sample_station_${item.dataset_name}`, ["symbol"], ["#FFFFFF", "#FFFFFF"], "visible", "dataSearchMap", "dsds", "sample_name");
|
loadVectorLayer({ layerId: `sample_station_${item.dataset_name}`, features: ["symbol"], colors: ["#FFFFFF", "#FFFFFF"], visibility: "visible", mapId: "dataSearchMap", workspace: "dsds", textField: "sample_name", callbackOnClick: this.setHightItem });
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
})
|
})
|
||||||
|
|
@ -559,6 +556,13 @@ export default {
|
||||||
this.dataList = voyageList
|
this.dataList = voyageList
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setHightItem(item) {
|
||||||
|
// 单击地图上的样品后,在左侧列表中高亮对应项
|
||||||
|
this.currenSample = item.properties.tsy_id;
|
||||||
|
// this.currenId = item.properties.tsy_id;
|
||||||
|
console.log("clicked item:", item);
|
||||||
|
},
|
||||||
|
|
||||||
turnDeatilPage(item) {
|
turnDeatilPage(item) {
|
||||||
this.dialog5 = true
|
this.dialog5 = true
|
||||||
regInfo({ voyage_name: item.voyage_name }).then(res => {
|
regInfo({ voyage_name: item.voyage_name }).then(res => {
|
||||||
|
|
@ -636,9 +640,14 @@ export default {
|
||||||
});
|
});
|
||||||
let layerId = `vector-${job_type == "测线作业" ? "sample_line" : "sample_station"}_${sample.dataset_name}-${job_type == "测线作业" ? "line" : "symbol"}`;
|
let layerId = `vector-${job_type == "测线作业" ? "sample_line" : "sample_station"}_${sample.dataset_name}-${job_type == "测线作业" ? "line" : "symbol"}`;
|
||||||
let sourceLayerId = `${job_type == "测线作业" ? "sample_line" : "sample_station"}_${sample.dataset_name}`;
|
let sourceLayerId = `${job_type == "测线作业" ? "sample_line" : "sample_station"}_${sample.dataset_name}`;
|
||||||
|
// triggerLayerClick("dataSearchMap", sourceLayerId, layerId, [lon, lat], { "sample_name": sample.sample_name });
|
||||||
|
// 单击样品时,同步在地图上显示样品信息弹窗
|
||||||
|
showHighlightSampleInfo({ mapId: "dataSearchMap", job_type, sample, layerId, sourceLayerId });
|
||||||
|
// 将选中的图层移动到最顶层,传入 undefined 作为第二个参数即可
|
||||||
|
Vue.config.maps["dataSearchMap"].moveLayer(layerId, undefined);
|
||||||
|
|
||||||
// vector-sample_station_TS-46-1_FDZ377_Slurp_SWYP-symbol、vector-sample_line_TS2-29-1_SY612_GQXJ_PJZP-line
|
// vector-sample_station_TS-46-1_FDZ377_Slurp_SWYP-symbol、vector-sample_line_TS2-29-1_SY612_GQXJ_PJZP-line
|
||||||
// highlightFeaturesByProperty("dataSearchMap", `${job_type == "测线作业" ? "sample_line" : "sample_station"}_${sample.dataset_name}`, layerId, "sample_name", sample.sample_name);
|
// highlightFeaturesByProperty("dataSearchMap", `${job_type == "测线作业" ? "sample_line" : "sample_station"}_${sample.dataset_name}`, layerId, "sample_name", sample.sample_name);
|
||||||
triggerLayerClick("dataSearchMap", sourceLayerId, layerId, [lon, lat], { "sample_name": sample.sample_name });
|
|
||||||
},
|
},
|
||||||
goHome() {
|
goHome() {
|
||||||
this.$router.push({ name: 'home' })
|
this.$router.push({ name: 'home' })
|
||||||
|
|
@ -748,7 +757,7 @@ export default {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
> .rule-text {
|
>.rule-text {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
|
@ -758,7 +767,7 @@ export default {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .left4 {
|
>.left4 {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
@ -999,5 +1008,4 @@ export default {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: none !important;
|
background: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -328,8 +328,8 @@ export default {
|
||||||
// 加载海岸线
|
// 加载海岸线
|
||||||
// loadVectorLayer("GSHHS_f_L1", ["line"], ["#FEFEFE"], "homeMap", 'ougp');
|
// loadVectorLayer("GSHHS_f_L1", ["line"], ["#FEFEFE"], "homeMap", 'ougp');
|
||||||
// 加载等深线(默认不显示)
|
// 加载等深线(默认不显示)
|
||||||
loadVectorLayer("contour-4500m", ["line"], ["#FEFEFE"], "none", "homeMap", 'ougp');
|
loadVectorLayer({ layerId: "contour-4500m", features: ["line"], colors: ["#FEFEFE"], visibility: "none", mapId: "homeMap", workspace: 'ougp' });
|
||||||
loadVectorLayer("contour-6000m", ["line"], ["#FEFEFE"], "none", "homeMap", 'ougp');
|
loadVectorLayer({ layerId: "contour-6000m", features: ["line"], colors: ["#FEFEFE"], visibility: "none", mapId: "homeMap", workspace: 'ougp' });
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -345,7 +345,7 @@ export default {
|
||||||
const colors = ColorGenerator.generateDivergingColors(this.voyageList.length);
|
const colors = ColorGenerator.generateDivergingColors(this.voyageList.length);
|
||||||
this.voyageList.forEach(element => {
|
this.voyageList.forEach(element => {
|
||||||
// 加载轨迹图层
|
// 加载轨迹图层
|
||||||
loadVectorLayer(element.voyage_name, ["line", "symbol"], [colors[i], colors[i]], "visible", "homeMap", "dsds");
|
loadVectorLayer({ layerId: element.voyage_name, features: ["line", "symbol"], colors: [colors[i], colors[i]], visibility: "visible", mapId: "homeMap", workspace: "dsds" });
|
||||||
i++;
|
i++;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,15 +63,16 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Vue from 'vue'
|
||||||
/**
|
/**
|
||||||
* 水下自主式无人潜器汇总统计页;Banner 平台名来自 `/report/platform/name.htm`,其余请求 `/report/platform/auv` 系列;交互与遥控潜水器汇总页一致(ECharts)。
|
* 水下自主式无人潜器汇总统计页;Banner 平台名来自 `/report/platform/name.htm`,其余请求 `/report/platform/auv` 系列;交互与遥控潜水器汇总页一致(ECharts)。
|
||||||
*/
|
*/
|
||||||
import BarChart from './components/BarChart.vue'
|
import BarChart from './components/BarChart.vue'
|
||||||
import PieChart from './components/PieChart.vue'
|
import PieChart from './components/PieChart.vue'
|
||||||
import { platformNameList, platformAuv, auvUnit, auvUnitYear, auvDiving } from '../../api/statistics'
|
import { platformNameList, platformAuv, auvUnit, auvUnitYear, auvDiving } from '../../api/statistics'
|
||||||
import { initMapbox, handleWheel, initSprites, triggerLayerClick } from "@/utils/mapbox-utils";
|
import { initMapbox } from '@/utils/mapbox-utils'
|
||||||
import { loadVectorLayer, loadJsonLineFeature, loadJsonPointFeature, highlightFeaturesByProperty } from '@/utils/vector-layer-utils'
|
import { loadVectorLayer, loadJsonPointFeature, showUnitReport } from '@/utils/vector-layer-utils'
|
||||||
import { ColorGenerator } from '@/utils/color-generator';
|
import { ColorGenerator } from '@/utils/color-generator'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -221,6 +222,13 @@ export default {
|
||||||
});
|
});
|
||||||
loadJsonPointFeature("workUnit", "blue", geojson, "unit_name", "workUnitMap_auv");
|
loadJsonPointFeature("workUnit", "blue", geojson, "unit_name", "workUnitMap_auv");
|
||||||
|
|
||||||
|
Vue.config.maps['workUnitMap_auv'].on('click', 'workUnit', async (e) => {
|
||||||
|
if (!e.features || e.features.length <= 0)
|
||||||
|
return;
|
||||||
|
// 地图点选弹窗显示单位信息
|
||||||
|
showUnitReport('workUnitMap_auv', e.features[0].properties.unit_name, e.features[0].geometry.coordinates);
|
||||||
|
});
|
||||||
|
|
||||||
const typeCount = res.array.reduce((acc, unit) => {
|
const typeCount = res.array.reduce((acc, unit) => {
|
||||||
const type = unit.unit_type
|
const type = unit.unit_type
|
||||||
acc[type] = (acc[type] || 0) + 1 // 如果类型已存在则计数+1,否则初始化为1
|
acc[type] = (acc[type] || 0) + 1 // 如果类型已存在则计数+1,否则初始化为1
|
||||||
|
|
@ -241,7 +249,7 @@ export default {
|
||||||
// 添加轨迹图层
|
// 添加轨迹图层
|
||||||
res.array.forEach(item => {
|
res.array.forEach(item => {
|
||||||
// 加载轨迹图层
|
// 加载轨迹图层
|
||||||
loadVectorLayer(item.diving_sn, ["line", "symbol"], [colors[i], "#FFFFFF"], "visible", "voyageMap_auv", "dsds");
|
loadVectorLayer({ layerId: item.diving_sn, features: ["line", "symbol"], colors: [colors[i], "#FFFFFF"], visibility: "visible", mapId: "voyageMap_auv", worksapce: "dsds" });
|
||||||
i++;
|
i++;
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -63,13 +63,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Vue from 'vue'
|
||||||
import BarChart from './components/BarChart.vue'
|
import BarChart from './components/BarChart.vue'
|
||||||
import PieChart from './components/PieChart.vue'
|
import PieChart from './components/PieChart.vue'
|
||||||
import { setImageryViewModels } from '../../utils/common'
|
|
||||||
import { reportList, platformHov, hovUnit, hovUnitYear, hovDiving } from '../../api/statistics'
|
import { reportList, platformHov, hovUnit, hovUnitYear, hovDiving } from '../../api/statistics'
|
||||||
import { filterDictItems } from '../../utils/index'
|
import { filterDictItems } from '../../utils/index'
|
||||||
import { initMapbox, handleWheel, initSprites, triggerLayerClick } from "@/utils/mapbox-utils";
|
import { initMapbox } from "@/utils/mapbox-utils";
|
||||||
import { loadVectorLayer, loadJsonLineFeature, loadJsonPointFeature, highlightFeaturesByProperty } from '@/utils/vector-layer-utils'
|
import { setMapLayoutProperty, loadVectorLayer, loadJsonPointFeature, showUnitReport } from '@/utils/vector-layer-utils'
|
||||||
import { ColorGenerator } from '@/utils/color-generator';
|
import { ColorGenerator } from '@/utils/color-generator';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -157,7 +157,6 @@ export default {
|
||||||
// 选择载人潜水器
|
// 选择载人潜水器
|
||||||
handleCommand(command) {
|
handleCommand(command) {
|
||||||
this.currentTitle = command
|
this.currentTitle = command
|
||||||
this.removeSingleLineImg()
|
|
||||||
if (command === '全部载人潜水器') {
|
if (command === '全部载人潜水器') {
|
||||||
this.getHovList()
|
this.getHovList()
|
||||||
this.gitHovDiving()
|
this.gitHovDiving()
|
||||||
|
|
@ -204,6 +203,13 @@ export default {
|
||||||
});
|
});
|
||||||
loadJsonPointFeature("workUnit", "blue", geojson, "unit_name", "workUnitMap_hov");
|
loadJsonPointFeature("workUnit", "blue", geojson, "unit_name", "workUnitMap_hov");
|
||||||
|
|
||||||
|
Vue.config.maps['workUnitMap_hov'].on('click', 'workUnit', async (e) => {
|
||||||
|
if (!e.features || e.features.length <= 0)
|
||||||
|
return;
|
||||||
|
// 地图点选弹窗显示单位信息
|
||||||
|
showUnitReport('workUnitMap_hov', e.features[0].properties.unit_name, e.features[0].geometry.coordinates);
|
||||||
|
});
|
||||||
|
|
||||||
const typeCount = res.array.reduce((acc, unit) => {
|
const typeCount = res.array.reduce((acc, unit) => {
|
||||||
const type = unit.unit_type
|
const type = unit.unit_type
|
||||||
acc[type] = (acc[type] || 0) + 1 // 如果类型已存在则计数+1,否则初始化为1
|
acc[type] = (acc[type] || 0) + 1 // 如果类型已存在则计数+1,否则初始化为1
|
||||||
|
|
@ -219,15 +225,17 @@ export default {
|
||||||
// 潜次统计
|
// 潜次统计
|
||||||
gitHovDiving(params = {}) {
|
gitHovDiving(params = {}) {
|
||||||
hovDiving(params).then(res => {
|
hovDiving(params).then(res => {
|
||||||
|
if (params.platform_name) {
|
||||||
|
// 按潜水器筛选数据,先隐藏所有图层,再根据筛选结果显示对应图层
|
||||||
|
setMapLayoutProperty('voyageMap_hov', 'none')
|
||||||
|
}
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
const colors = ColorGenerator.generateDivergingColors(res.array.length);
|
const colors = ColorGenerator.generateDivergingColors(res.array.length);
|
||||||
// 添加轨迹图层
|
|
||||||
res.array.forEach(item => {
|
res.array.forEach(item => {
|
||||||
// 加载轨迹图层
|
// 加载下潜轨迹
|
||||||
loadVectorLayer(item.diving_sn, ["line", "symbol"], [colors[i], "#FFFFFF"], "visible", "voyageMap_hov", "dsds");
|
loadVectorLayer({ layerId: item.diving_sn, features: ["line", "symbol"], colors: [colors[i], "#FFFFFF"], visibility: "visible", mapId: "voyageMap_hov", workspace: "dsds" });
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
// this.addSingleLineImg(item)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Vue from 'vue'
|
||||||
/**
|
/**
|
||||||
* 遥控潜水器汇总统计页,请求 `/report/platform/rov` 系列接口。
|
* 遥控潜水器汇总统计页,请求 `/report/platform/rov` 系列接口。
|
||||||
*/
|
*/
|
||||||
|
|
@ -70,8 +71,8 @@ import BarChart from './components/BarChart.vue'
|
||||||
import PieChart from './components/PieChart.vue'
|
import PieChart from './components/PieChart.vue'
|
||||||
import { reportList, platformRov, rovUnit, rovUnitYear, rovDiving } from '../../api/statistics'
|
import { reportList, platformRov, rovUnit, rovUnitYear, rovDiving } from '../../api/statistics'
|
||||||
import { filterDictItems } from '../../utils/index'
|
import { filterDictItems } from '../../utils/index'
|
||||||
import { initMapbox, handleWheel, initSprites, triggerLayerClick } from "@/utils/mapbox-utils";
|
import { initMapbox } from "@/utils/mapbox-utils";
|
||||||
import { loadVectorLayer, loadJsonLineFeature, loadJsonPointFeature, highlightFeaturesByProperty } from '@/utils/vector-layer-utils'
|
import { loadVectorLayer, loadJsonPointFeature, showUnitReport } from '@/utils/vector-layer-utils'
|
||||||
import { ColorGenerator } from '@/utils/color-generator';
|
import { ColorGenerator } from '@/utils/color-generator';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -206,6 +207,13 @@ export default {
|
||||||
});
|
});
|
||||||
loadJsonPointFeature("workUnit", "blue", geojson, "unit_name", "workUnitMap_rov");
|
loadJsonPointFeature("workUnit", "blue", geojson, "unit_name", "workUnitMap_rov");
|
||||||
|
|
||||||
|
Vue.config.maps['workUnitMap_rov'].on('click', 'workUnit', async (e) => {
|
||||||
|
if (!e.features || e.features.length <= 0)
|
||||||
|
return;
|
||||||
|
// 地图点选弹窗显示单位信息
|
||||||
|
showUnitReport('workUnitMap_rov', e.features[0].properties.unit_name, e.features[0].geometry.coordinates);
|
||||||
|
});
|
||||||
|
|
||||||
const typeCount = res.array.reduce((acc, unit) => {
|
const typeCount = res.array.reduce((acc, unit) => {
|
||||||
const type = unit.unit_type
|
const type = unit.unit_type
|
||||||
acc[type] = (acc[type] || 0) + 1 // 如果类型已存在则计数+1,否则初始化为1
|
acc[type] = (acc[type] || 0) + 1 // 如果类型已存在则计数+1,否则初始化为1
|
||||||
|
|
@ -226,7 +234,7 @@ export default {
|
||||||
// 添加轨迹图层
|
// 添加轨迹图层
|
||||||
res.array.forEach(item => {
|
res.array.forEach(item => {
|
||||||
// 加载轨迹图层
|
// 加载轨迹图层
|
||||||
loadVectorLayer(item.diving_sn, ["line", "symbol"], [colors[i], "#FFFFFF"], "visible", "voyageMap_rov", "dsds");
|
loadVectorLayer({ layerId: item.diving_sn, features: ["line", "symbol"], colors: [colors[i], "#FFFFFF"], visibility: "visible", mapId: "voyageMap_rov", workspace: "dsds" });
|
||||||
i++;
|
i++;
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -69,12 +69,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Vue from 'vue'
|
||||||
import BarChart from './components/BarChart.vue'
|
import BarChart from './components/BarChart.vue'
|
||||||
import PieChart from './components/PieChart.vue'
|
import PieChart from './components/PieChart.vue'
|
||||||
import { reportList, shipTotal, shipUnit, shipUnitYear, shipVoyage } from '../../api/statistics'
|
import { reportList, shipTotal, shipUnit, shipUnitYear, shipVoyage } from '../../api/statistics'
|
||||||
import { getYearRange, filterDictItems } from '../../utils/index'
|
import { getYearRange, filterDictItems } from '../../utils/index'
|
||||||
import { initMapbox } from '@/utils/mapbox-utils'
|
import { initMapbox } from '@/utils/mapbox-utils'
|
||||||
import { loadVectorLayer, loadJsonPointFeature } from '@/utils/vector-layer-utils'
|
import { setMapLayoutProperty, loadVectorLayer, loadJsonPointFeature, showUnitReport } from '@/utils/vector-layer-utils'
|
||||||
import { ColorGenerator } from '@/utils/color-generator'
|
import { ColorGenerator } from '@/utils/color-generator'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -169,7 +170,6 @@ export default {
|
||||||
// 选择科考船
|
// 选择科考船
|
||||||
handleCommand(command) {
|
handleCommand(command) {
|
||||||
this.currentTitle = command
|
this.currentTitle = command
|
||||||
// this.removeSingleLineImg()
|
|
||||||
if (command === '全部科考船') {
|
if (command === '全部科考船') {
|
||||||
this.getShipList()
|
this.getShipList()
|
||||||
this.gitShipVoyage()
|
this.gitShipVoyage()
|
||||||
|
|
@ -186,7 +186,7 @@ export default {
|
||||||
getShipList(params = {}) {
|
getShipList(params = {}) {
|
||||||
shipTotal(params).then(res => {
|
shipTotal(params).then(res => {
|
||||||
const obj = res.array[0]
|
const obj = res.array[0]
|
||||||
this.numbers[0].value = obj.member_total
|
this.numbers[0].value = obj.voyage_total
|
||||||
this.numbers[1].value = obj.days_total
|
this.numbers[1].value = obj.days_total
|
||||||
this.numbers[2].value = obj.unit_total
|
this.numbers[2].value = obj.unit_total
|
||||||
this.numbers[3].value = obj.dataset_total
|
this.numbers[3].value = obj.dataset_total
|
||||||
|
|
@ -217,6 +217,13 @@ export default {
|
||||||
})
|
})
|
||||||
loadJsonPointFeature('workUnit', 'blue', geojson, 'unit_name', 'workUnitMap_ship')
|
loadJsonPointFeature('workUnit', 'blue', geojson, 'unit_name', 'workUnitMap_ship')
|
||||||
|
|
||||||
|
Vue.config.maps['workUnitMap_ship'].on('click', 'workUnit', async (e) => {
|
||||||
|
if (!e.features || e.features.length <= 0)
|
||||||
|
return;
|
||||||
|
// 地图点选弹窗显示单位信息
|
||||||
|
showUnitReport('workUnitMap_ship', e.features[0].properties.unit_name, e.features[0].geometry.coordinates);
|
||||||
|
});
|
||||||
|
|
||||||
const typeCount = res.array.reduce((acc, unit) => {
|
const typeCount = res.array.reduce((acc, unit) => {
|
||||||
const type = unit.unit_type
|
const type = unit.unit_type
|
||||||
acc[type] = (acc[type] || 0) + 1 // 如果类型已存在则计数+1,否则初始化为1
|
acc[type] = (acc[type] || 0) + 1 // 如果类型已存在则计数+1,否则初始化为1
|
||||||
|
|
@ -232,12 +239,17 @@ export default {
|
||||||
// 航次统计
|
// 航次统计
|
||||||
gitShipVoyage(params = {}) {
|
gitShipVoyage(params = {}) {
|
||||||
shipVoyage(params).then(res => {
|
shipVoyage(params).then(res => {
|
||||||
|
if (params.start || params.end || params.ship_name) {
|
||||||
|
// 按年份筛选数据,先隐藏所有图层,再根据筛选结果显示对应图层
|
||||||
|
setMapLayoutProperty('voyageMap_ship', 'none')
|
||||||
|
}
|
||||||
|
|
||||||
let i = 0
|
let i = 0
|
||||||
const colors = ColorGenerator.generateDivergingColors(res.array.length)
|
const colors = ColorGenerator.generateDivergingColors(res.array.length)
|
||||||
// 添加轨迹图层
|
// 添加轨迹图层
|
||||||
res.array.forEach(item => {
|
res.array.forEach(item => {
|
||||||
// 加载轨迹图层
|
// 加载轨迹图层(已存在则设置为可见)
|
||||||
loadVectorLayer(item.voyage_name, ['line', 'symbol'], [colors[i], '#FFFFFF'], 'visible', 'voyageMap_ship', 'dsds')
|
loadVectorLayer({ layerId: item.voyage_name, features: ['line', 'symbol'], colors: [colors[i], '#FFFFFF'], visibility: 'visible', mapId: 'voyageMap_ship', workspace: 'dsds' })
|
||||||
i++
|
i++
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -247,7 +259,6 @@ export default {
|
||||||
selectVoyageYear(val) {
|
selectVoyageYear(val) {
|
||||||
const shipName = this.currentTitle === '全部科考船' ? '' : this.currentTitle
|
const shipName = this.currentTitle === '全部科考船' ? '' : this.currentTitle
|
||||||
if (val) {
|
if (val) {
|
||||||
// this.removeSingleLineImg()
|
|
||||||
const params = getYearRange(val)
|
const params = getYearRange(val)
|
||||||
this.gitShipVoyage({ ...params, ship_name: shipName })
|
this.gitShipVoyage({ ...params, ship_name: shipName })
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -284,7 +295,7 @@ export default {
|
||||||
const sortedData = originalData.sort((a, b) => a.year - b.year)
|
const sortedData = originalData.sort((a, b) => a.year - b.year)
|
||||||
this.barData1 = {
|
this.barData1 = {
|
||||||
title: '年度航次数',
|
title: '年度航次数',
|
||||||
salesData: sortedData.map(item => item.member_total),
|
salesData: sortedData.map(item => item.voyage_total),
|
||||||
productCategories: sortedData.map(item => item.year.toString())
|
productCategories: sortedData.map(item => item.year.toString())
|
||||||
}
|
}
|
||||||
this.barDataDays = {
|
this.barDataDays = {
|
||||||
|
|
|
||||||
|
|
@ -86,9 +86,8 @@ import Vue from 'vue'
|
||||||
import BarChart from './components/BarChart.vue'
|
import BarChart from './components/BarChart.vue'
|
||||||
import { unitTotal, hovUnit, shipUnit, shipVoyage } from '../../api/statistics'
|
import { unitTotal, hovUnit, shipUnit, shipVoyage } from '../../api/statistics'
|
||||||
import { getYearRange } from '../../utils/index'
|
import { getYearRange } from '../../utils/index'
|
||||||
import { initMapbox, handleWheel } from '@/utils/mapbox-utils'
|
import { initMapbox } from '@/utils/mapbox-utils'
|
||||||
import { loadVectorLayer, loadJsonPointFeature } from '@/utils/vector-layer-utils'
|
import { loadJsonPointFeature, showUnitReport } from '@/utils/vector-layer-utils'
|
||||||
import { ColorGenerator } from '@/utils/color-generator'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {*} v 原始值
|
* @param {*} v 原始值
|
||||||
|
|
@ -113,6 +112,8 @@ export default {
|
||||||
selectedUnits: [],
|
selectedUnits: [],
|
||||||
/** unitTotal 全量缓存,便于按 Banner 选择做前端过滤 */
|
/** unitTotal 全量缓存,便于按 Banner 选择做前端过滤 */
|
||||||
unitTotalRawList: [],
|
unitTotalRawList: [],
|
||||||
|
// 全量单位列表,用于地图点选时绑定 Banner
|
||||||
|
totalUnits: [],
|
||||||
numbers: [
|
numbers: [
|
||||||
{
|
{
|
||||||
label: '参航单位数量',
|
label: '参航单位数量',
|
||||||
|
|
@ -167,23 +168,15 @@ export default {
|
||||||
this.loadUnitTotalFromApi()
|
this.loadUnitTotalFromApi()
|
||||||
this.getHovUnit()
|
this.getHovUnit()
|
||||||
this.getShipUnit()
|
this.getShipUnit()
|
||||||
this.gitShipVoyage()
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
initMapbox('workUnitMap_uuv', {
|
initMapbox('workUnitMap_uuv', {
|
||||||
tileKey: 'gaode',
|
tileKey: 'gaode',
|
||||||
zoom: 3,
|
zoom: 2.8,
|
||||||
center: [110, 33],
|
center: [120, 31],
|
||||||
minZoom: 2,
|
minZoom: 2,
|
||||||
maxZoom: 29
|
maxZoom: 29
|
||||||
})
|
})
|
||||||
// initMapbox('voyageMap_uuv', {
|
|
||||||
// tileKey: 'GEBCO_basemap_NCEI',
|
|
||||||
// zoom: 3,
|
|
||||||
// center: [113, 15],
|
|
||||||
// minZoom: 2,
|
|
||||||
// maxZoom: 29
|
|
||||||
// })
|
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
const unitMap = Vue.config.maps && Vue.config.maps['workUnitMap_uuv']
|
const unitMap = Vue.config.maps && Vue.config.maps['workUnitMap_uuv']
|
||||||
|
|
@ -191,11 +184,6 @@ export default {
|
||||||
unitMap.remove()
|
unitMap.remove()
|
||||||
delete Vue.config.maps['workUnitMap_uuv']
|
delete Vue.config.maps['workUnitMap_uuv']
|
||||||
}
|
}
|
||||||
const voyageMap = Vue.config.maps && Vue.config.maps['voyageMap_uuv']
|
|
||||||
if (voyageMap) {
|
|
||||||
voyageMap.remove()
|
|
||||||
delete Vue.config.maps['voyageMap_uuv']
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/**
|
/**
|
||||||
|
|
@ -224,6 +212,10 @@ export default {
|
||||||
const nameSet = new Set(sel.map(u => u && u.unit_name).filter(Boolean))
|
const nameSet = new Set(sel.map(u => u && u.unit_name).filter(Boolean))
|
||||||
const filtered = raw.filter(row => nameSet.has(row.unit_name))
|
const filtered = raw.filter(row => nameSet.has(row.unit_name))
|
||||||
this.applyUnitTotalRows(filtered)
|
this.applyUnitTotalRows(filtered)
|
||||||
|
|
||||||
|
console.log('applyFilteredUnitTotal', this.selectedUnits);
|
||||||
|
// 地图显示最后一个选中单位的相关信息
|
||||||
|
showUnitReport('workUnitMap_uuv', this.selectedUnits.at(-1).unit_name, [this.selectedUnits.at(-1).unit_lon, this.selectedUnits.at(-1).unit_lat])
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -337,12 +329,13 @@ export default {
|
||||||
*/
|
*/
|
||||||
getHovUnit() {
|
getHovUnit() {
|
||||||
hovUnit().then(res => {
|
hovUnit().then(res => {
|
||||||
const map = new Map()
|
// 参航单位不一定下潜
|
||||||
; (res.array || []).forEach(unit => {
|
// const map = new Map();
|
||||||
const k = unit.unit_id || unit.unitId || unit.unit_name
|
// (res.array || []).forEach(unit => {
|
||||||
if (!map.has(k)) map.set(k, unit)
|
// const k = unit.unit_id || unit.unitId || unit.unit_name
|
||||||
})
|
// if (!map.has(k)) map.set(k, unit)
|
||||||
this.unitOptions = Array.from(map.values())
|
// })
|
||||||
|
// this.unitOptions = Array.from(map.values());
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -352,11 +345,19 @@ export default {
|
||||||
*/
|
*/
|
||||||
getShipUnit() {
|
getShipUnit() {
|
||||||
shipUnit().then(res => {
|
shipUnit().then(res => {
|
||||||
|
this.totalUnits = res.array || [];
|
||||||
|
const map = new Map();
|
||||||
|
this.totalUnits.forEach(unit => {
|
||||||
|
const k = unit.unit_id || unit.unitId || unit.unit_name
|
||||||
|
if (!map.has(k)) map.set(k, unit)
|
||||||
|
})
|
||||||
|
this.unitOptions = Array.from(map.values())
|
||||||
|
|
||||||
const geojson = {
|
const geojson = {
|
||||||
type: 'FeatureCollection',
|
type: 'FeatureCollection',
|
||||||
features: []
|
features: []
|
||||||
}
|
};
|
||||||
; (res.array || []).forEach(element => {
|
this.totalUnits.forEach(element => {
|
||||||
geojson.features.push({
|
geojson.features.push({
|
||||||
type: 'Feature',
|
type: 'Feature',
|
||||||
geometry: {
|
geometry: {
|
||||||
|
|
@ -370,39 +371,27 @@ export default {
|
||||||
tsy_id: element.tsy_id
|
tsy_id: element.tsy_id
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
});
|
||||||
loadJsonPointFeature('workUnit', 'blue', geojson, 'unit_name', 'workUnitMap_uuv')
|
loadJsonPointFeature('workUnit', 'blue', geojson, 'unit_name', 'workUnitMap_uuv');
|
||||||
|
|
||||||
|
Vue.config.maps['workUnitMap_uuv'].on('click', 'workUnit', async (e) => {
|
||||||
|
if (!e.features || e.features.length <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 绑定地图单击的单位与 Banner 选项,保持地图点选与 Banner 选项同步
|
||||||
|
this.selectedUnits = this.totalUnits.filter(u => u.unit_name === e.features[0].properties.unit_name);
|
||||||
|
// 地图点选弹窗显示单位信息
|
||||||
|
showUnitReport('workUnitMap_uuv', e.features[0].properties.unit_name, e.features[0].geometry.coordinates, this.resetFilter);
|
||||||
|
// 同步更新单位统计图
|
||||||
|
this.applyUnitTotalRows((this.unitTotalRawList || []).filter(row => row.unit_name === e.features[0].properties.unit_name));
|
||||||
|
});
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
resetFilter() {
|
||||||
* 科考船航次轨迹(与 ships 页地图同源接口),通过 Mapbox 矢量图层渲染。
|
// 关闭地图弹窗后恢复全部单位统计显示
|
||||||
* @param {Object} [params] 查询参数
|
this.selectedUnits = [];
|
||||||
* @returns {void}
|
this.applyUnitTotalRows(this.unitTotalRawList || []);
|
||||||
*/
|
|
||||||
gitShipVoyage(params = {}) {
|
|
||||||
shipVoyage(params).then(res => {
|
|
||||||
let i = 0
|
|
||||||
const colors = ColorGenerator.generateDivergingColors((res.array || []).length)
|
|
||||||
; (res.array || []).forEach(item => {
|
|
||||||
loadVectorLayer(item.voyage_name, ['line', 'symbol'], [colors[i], '#FFFFFF'], 'visible', 'voyageMap_uuv', 'dsds')
|
|
||||||
i++
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 选择航次地图年份。
|
|
||||||
* @param {*} val 年份值
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
selectVoyageYear(val) {
|
|
||||||
if (val) {
|
|
||||||
const params = getYearRange(val)
|
|
||||||
this.gitShipVoyage({ ...params })
|
|
||||||
} else {
|
|
||||||
this.gitShipVoyage({})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -359,7 +359,7 @@ export default {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
{ label: '航次', display: this.formatMetric(s.member_total) + ' 次' },
|
{ label: '航次', display: this.formatMetric(s.voyage_total) + ' 次' },
|
||||||
{ label: '航次天数', display: this.formatMetric(s.days_total) + ' 天' },
|
{ label: '航次天数', display: this.formatMetric(s.days_total) + ' 天' },
|
||||||
{ label: '参航单位', display: this.formatMetric(s.unit_total) + ' 家' },
|
{ label: '参航单位', display: this.formatMetric(s.unit_total) + ' 家' },
|
||||||
{ label: '数据样品', display: this.formatMetric(s.dataset_total) + ' 个' }
|
{ label: '数据样品', display: this.formatMetric(s.dataset_total) + ' 个' }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue