2026-04-20 16:57:54 +08:00
|
|
|
|
// import { Session } from '@zebras/qgc-share/service/Session'
|
2026-06-01 08:42:06 +08:00
|
|
|
|
import domtoimage from 'dom-to-image';
|
|
|
|
|
|
import {
|
|
|
|
|
|
offset2,
|
|
|
|
|
|
drawDotImg2,
|
|
|
|
|
|
drawDotImg1,
|
|
|
|
|
|
offset1,
|
|
|
|
|
|
drawDotImg3,
|
|
|
|
|
|
offset3,
|
|
|
|
|
|
drawDotImg5,
|
|
|
|
|
|
offset5
|
|
|
|
|
|
} from '@/utils/GisUrlList';
|
2026-07-31 11:13:49 +08:00
|
|
|
|
import { LAYOUT_GRID_SKELETONS } from '@/views/dianZhanZhuanTi/layoutGridSkeletons';
|
2026-08-31 14:04:06 +08:00
|
|
|
|
import { useUiStore } from '@/store/modules/ui';
|
2026-04-22 17:53:20 +08:00
|
|
|
|
declare global {
|
2026-06-01 08:42:06 +08:00
|
|
|
|
interface Window {
|
|
|
|
|
|
__lyConfigs?: {
|
|
|
|
|
|
theme?: string;
|
|
|
|
|
|
[key: string]: any; // 根据实际配置结构补充具体字段,或使用索引签名兼容其他属性
|
|
|
|
|
|
};
|
|
|
|
|
|
__mapMode?: string; // 建议同时声明代码中用到的其他全局变量
|
|
|
|
|
|
}
|
2026-04-22 17:53:20 +08:00
|
|
|
|
}
|
2026-06-01 08:42:06 +08:00
|
|
|
|
|
2026-04-20 16:57:54 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 根据镜头高度获取地图级别
|
|
|
|
|
|
* @param {Number} height
|
|
|
|
|
|
*/
|
2026-06-01 08:42:06 +08:00
|
|
|
|
const A = 40487.57;
|
|
|
|
|
|
const B = 0.00007096758;
|
|
|
|
|
|
const C = 91610.74;
|
|
|
|
|
|
const D = -40467.74;
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 图例数据转对象
|
|
|
|
|
|
* @param data 图例数据
|
|
|
|
|
|
* @returns 以nameEn为下标的图例数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
export const legendData2Obj = (data: any[]) => {
|
2026-06-01 08:42:06 +08:00
|
|
|
|
const _tempData: any = {};
|
|
|
|
|
|
const f = (_data: any[]) => {
|
|
|
|
|
|
_data.forEach(item => {
|
|
|
|
|
|
// childrenList有值表示这是一个分组
|
|
|
|
|
|
if (item?.childrenList && item.childrenList?.length > 0) {
|
|
|
|
|
|
f(item.childrenList);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
_tempData[item.nameEn] = item;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
f(data);
|
|
|
|
|
|
return _tempData;
|
|
|
|
|
|
};
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 添加标签偏移量等属性到item中
|
|
|
|
|
|
* @param item - 待添加属性的item
|
|
|
|
|
|
* @param index - item的索引
|
|
|
|
|
|
* @param labelType - 标签类型
|
|
|
|
|
|
*/
|
2026-06-05 16:10:14 +08:00
|
|
|
|
export const appendOffsetPropties = (item: any, index: any, labelType = 2) => {
|
2026-06-01 08:42:06 +08:00
|
|
|
|
let drawDotImg = null;
|
|
|
|
|
|
let offset = null;
|
|
|
|
|
|
if (labelType == 2) {
|
|
|
|
|
|
drawDotImg = drawDotImg1;
|
|
|
|
|
|
offset = offset1;
|
|
|
|
|
|
addItemProperty(item, index, drawDotImg, offset);
|
|
|
|
|
|
} else if (labelType == 3) {
|
|
|
|
|
|
drawDotImg = drawDotImg2;
|
|
|
|
|
|
offset = offset2;
|
|
|
|
|
|
addItemProperty(item, index, drawDotImg, offset);
|
|
|
|
|
|
} else if (labelType == 4) {
|
|
|
|
|
|
drawDotImg = drawDotImg3;
|
|
|
|
|
|
offset = offset3;
|
|
|
|
|
|
addItemProperty2(item, index, drawDotImg, offset);
|
|
|
|
|
|
} else if (labelType == 5) {
|
|
|
|
|
|
drawDotImg = drawDotImg5;
|
|
|
|
|
|
offset = offset5;
|
|
|
|
|
|
addItemProperty2(item, index, drawDotImg, offset);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
2026-06-01 08:42:06 +08:00
|
|
|
|
const addItemProperty2 = (
|
|
|
|
|
|
item: any,
|
|
|
|
|
|
index: any,
|
|
|
|
|
|
drawDotImg: any,
|
|
|
|
|
|
offset: any
|
|
|
|
|
|
) => {
|
|
|
|
|
|
if (!drawDotImg || !offset) return;
|
|
|
|
|
|
item.icon_image =
|
|
|
|
|
|
index % 2 !== 0
|
|
|
|
|
|
? drawDotImg[item.anchoPointState]?.left || ''
|
|
|
|
|
|
: drawDotImg[item.anchoPointState]?.right || '';
|
|
|
|
|
|
item.text_anchor = index % 2 !== 0 ? 'right' : 'left';
|
|
|
|
|
|
item.text_offset = offset[item.icon_image]?.text_offset ?? [-10, -1.8];
|
|
|
|
|
|
item.text_offset2 = offset[item.icon_image]?.text_offset2 ?? [-10, -1.8];
|
|
|
|
|
|
item.icon_offset = [
|
|
|
|
|
|
offset[item.icon_image]?.icon_x ?? -200,
|
|
|
|
|
|
offset[item.icon_image]?.icon_y ?? -50
|
|
|
|
|
|
];
|
|
|
|
|
|
item.icon_offset2 = offset[item.icon_image]?.icon_offset2 ?? [-200, -50];
|
|
|
|
|
|
item.billboard_offset = [
|
|
|
|
|
|
offset[item.icon_image]?.billboard_x ?? -80,
|
|
|
|
|
|
offset[item.icon_image]?.billboard_y ?? -15
|
|
|
|
|
|
];
|
|
|
|
|
|
item.label_offset = offset[item.icon_image]?.labelOffset ?? [100, 41];
|
|
|
|
|
|
};
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
2026-06-01 08:42:06 +08:00
|
|
|
|
export const addItemProperty = (
|
|
|
|
|
|
item: any,
|
|
|
|
|
|
index: any,
|
|
|
|
|
|
drawDotImg: any,
|
|
|
|
|
|
offset: any
|
|
|
|
|
|
) => {
|
|
|
|
|
|
if (!drawDotImg || !offset) return;
|
|
|
|
|
|
item.icon_image =
|
|
|
|
|
|
index % 2 !== 0
|
|
|
|
|
|
? drawDotImg[item.anchoPointState]?.left || ''
|
|
|
|
|
|
: drawDotImg[item.anchoPointState]?.right || '';
|
|
|
|
|
|
item.text_offset = [
|
|
|
|
|
|
offset[item.icon_image]?.text_x ?? -10,
|
|
|
|
|
|
offset[item.icon_image]?.text_y ?? -1.8
|
|
|
|
|
|
];
|
|
|
|
|
|
item.icon_offset = [
|
|
|
|
|
|
offset[item.icon_image]?.icon_x ?? -200,
|
|
|
|
|
|
offset[item.icon_image]?.icon_y ?? -50
|
|
|
|
|
|
];
|
|
|
|
|
|
item.billboard_offset = [
|
|
|
|
|
|
offset[item.icon_image]?.billboard_x ?? -80,
|
|
|
|
|
|
offset[item.icon_image]?.billboard_y ?? -15
|
|
|
|
|
|
];
|
|
|
|
|
|
item.label_offset = offset[item.icon_image]?.labelOffset ?? [100, 41];
|
|
|
|
|
|
};
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 设置popName属性
|
|
|
|
|
|
* @param item - 待设置popName的item
|
|
|
|
|
|
*/
|
|
|
|
|
|
export const setPopName = (item: any) => {
|
2026-06-01 08:42:06 +08:00
|
|
|
|
if (item.sttp === 'ENG') {
|
|
|
|
|
|
item.popName = item.ennm || item.titleName;
|
|
|
|
|
|
} else if (item.sttp === 'ylfb') {
|
|
|
|
|
|
if (item?.ftp?.length > 20) {
|
|
|
|
|
|
item.popName = item.ftp.slice(0, 20) + '...';
|
2026-04-20 16:57:54 +08:00
|
|
|
|
} else {
|
2026-06-01 08:42:06 +08:00
|
|
|
|
item.popName = item?.ftp;
|
2026-04-20 16:57:54 +08:00
|
|
|
|
}
|
2026-06-01 08:42:06 +08:00
|
|
|
|
} else if (item.sttp === 'WE_FISH') {
|
|
|
|
|
|
item.popName =
|
|
|
|
|
|
item.fishList?.[0]?.fishName + `(${item.fishList?.[0]?.ptypeName})`;
|
|
|
|
|
|
item.popName1 = item.total + '尾';
|
|
|
|
|
|
} else {
|
|
|
|
|
|
item.popName = item.stnm || item.titleName;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取图例配置中选中项的key
|
|
|
|
|
|
* @param data - 图例配置数据
|
|
|
|
|
|
* @returns 选中项的key数组
|
|
|
|
|
|
*/
|
|
|
|
|
|
export const getCheckedLayerConfigs = (data: any[]): any[] => {
|
2026-06-01 08:42:06 +08:00
|
|
|
|
const rs: any[] = [];
|
|
|
|
|
|
const f = (arr: any[] = []) => {
|
|
|
|
|
|
let count = 0;
|
|
|
|
|
|
arr.forEach((item: any) => {
|
|
|
|
|
|
if (item?.children && item.children.length > 0) {
|
|
|
|
|
|
const childrenCount = f(item.children);
|
|
|
|
|
|
if (childrenCount) {
|
|
|
|
|
|
rs.push(item.key);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (item.checked) {
|
|
|
|
|
|
count++;
|
|
|
|
|
|
rs.push(item.key); // 对应图例的layerCode
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
return count;
|
|
|
|
|
|
};
|
|
|
|
|
|
f(data);
|
|
|
|
|
|
return rs;
|
|
|
|
|
|
};
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
|
|
|
|
|
// type mapType = "" | "pointMap" | "gisLayer"
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 将图层配置数据转换为一维数组
|
|
|
|
|
|
* @param data - 图层配置数据
|
|
|
|
|
|
* @returns 一维数组
|
|
|
|
|
|
*/
|
|
|
|
|
|
export const layerConfig2Flat = (data: any): any[] => {
|
2026-06-01 08:42:06 +08:00
|
|
|
|
const rs: any[] = [];
|
|
|
|
|
|
const f = (arr: any[] = []) => {
|
|
|
|
|
|
arr.forEach((item: any) => {
|
|
|
|
|
|
const { type } = item;
|
|
|
|
|
|
if (type) {
|
2026-07-31 11:19:35 +08:00
|
|
|
|
if (type == 'GISMap' || type == 'geojson') {
|
2026-06-01 08:42:06 +08:00
|
|
|
|
if (item?.children && item.children.length > 0) {
|
|
|
|
|
|
f(item.children);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
rs.push(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (type == 'pointMap') {
|
|
|
|
|
|
if (
|
|
|
|
|
|
item.url ||
|
|
|
|
|
|
item.title === '国家水文站' ||
|
|
|
|
|
|
item.title === '自建水文站'
|
|
|
|
|
|
) {
|
|
|
|
|
|
rs.push(item);
|
|
|
|
|
|
} else if (item.children.length > 0) {
|
|
|
|
|
|
f(item.children);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (item.children.length > 0) {
|
|
|
|
|
|
f(item.children);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
f(data);
|
|
|
|
|
|
return rs;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 替换图层配置中的 URL
|
|
|
|
|
|
* @param layerConfigsArr - 图层配置数组
|
|
|
|
|
|
* @param urlList - URL 配置列表
|
|
|
|
|
|
* @returns 更新后的图层配置数组
|
|
|
|
|
|
*/
|
|
|
|
|
|
export const replaceUrl = (layerConfigsArr: any[], urlList: any[]): any[] => {
|
|
|
|
|
|
const bDict: Record<string, any[]> = {};
|
|
|
|
|
|
|
|
|
|
|
|
// 构建 URL 映射字典
|
|
|
|
|
|
for (let i = 0; i < urlList.length; i++) {
|
|
|
|
|
|
const key = urlList[i].url;
|
|
|
|
|
|
const title = urlList[i].title;
|
|
|
|
|
|
const keyType = urlList[i].keyType;
|
|
|
|
|
|
|
|
|
|
|
|
if (!bDict[key]) bDict[key] = [];
|
|
|
|
|
|
if (!bDict[title]) bDict[title] = [];
|
|
|
|
|
|
if (!bDict[keyType]) bDict[keyType] = [];
|
|
|
|
|
|
|
|
|
|
|
|
bDict[key].push(urlList[i]);
|
|
|
|
|
|
bDict[title].push(urlList[i]);
|
|
|
|
|
|
if (bDict[keyType]) {
|
|
|
|
|
|
bDict[keyType].push(urlList[i]);
|
2026-04-20 16:57:54 +08:00
|
|
|
|
}
|
2026-06-01 08:42:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 替换图层配置中的 URL
|
|
|
|
|
|
for (let i = 0; i < layerConfigsArr.length; i++) {
|
|
|
|
|
|
const obj = layerConfigsArr[i];
|
|
|
|
|
|
const key = obj.url;
|
|
|
|
|
|
const title = obj.title;
|
|
|
|
|
|
const keyType = obj.key;
|
|
|
|
|
|
|
|
|
|
|
|
const bObjList = bDict[keyType] || bDict[title] || bDict[key];
|
|
|
|
|
|
|
|
|
|
|
|
if (bObjList && bObjList.length > 0) {
|
|
|
|
|
|
const bObj = bObjList[0];
|
|
|
|
|
|
obj.url = bObj.url;
|
|
|
|
|
|
obj.urlThd = bObj.url;
|
|
|
|
|
|
obj.params = bObj.params;
|
|
|
|
|
|
obj.orders = bObj.orders;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
obj.url = '';
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return layerConfigsArr;
|
|
|
|
|
|
};
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取基础图层配置
|
|
|
|
|
|
* @param config - 接口获取的配置数据
|
|
|
|
|
|
* @returns 基础图层配置
|
|
|
|
|
|
*/
|
2026-06-01 08:42:06 +08:00
|
|
|
|
export const getMapConfig = (config: any) => {
|
|
|
|
|
|
const r = { ...config };
|
|
|
|
|
|
const baseUrlObj = import.meta.env.VITE_APP_MAP_URL;
|
|
|
|
|
|
if (baseUrlObj) {
|
|
|
|
|
|
r.url = baseUrlObj + r.url; // 'http://localhost:8088'
|
|
|
|
|
|
r.url_3d = baseUrlObj + r.url_3d;
|
|
|
|
|
|
// r.url = baseUrlObj.url + r.url //baseUrlObj.url
|
|
|
|
|
|
// r.url_3d = baseUrlObj.url + r.url_3d
|
|
|
|
|
|
if (r.geojson_url) {
|
|
|
|
|
|
r.geojson_url = baseUrlObj + r.geojson_url;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return r;
|
|
|
|
|
|
};
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 重置地图元素位置
|
|
|
|
|
|
*/
|
|
|
|
|
|
export const resetMapElPos = () => {
|
2026-06-01 08:42:06 +08:00
|
|
|
|
const legend = document.querySelector('#qgc-legendtl') as HTMLElement; // 图例
|
|
|
|
|
|
// const filter = document.querySelector('#map-filter-container') as HTMLElement // 全局表单
|
|
|
|
|
|
const controller = document.querySelector('#map-controller') as HTMLElement; // 地图工具栏
|
|
|
|
|
|
const baselayer = document.querySelector('#map-baselayer') as HTMLElement; // 底图模式切换
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
2026-06-01 08:42:06 +08:00
|
|
|
|
if (legend) {
|
|
|
|
|
|
legend.style.left = '0';
|
|
|
|
|
|
legend.style.bottom = '0';
|
|
|
|
|
|
}
|
|
|
|
|
|
if (controller) {
|
|
|
|
|
|
controller.style.right = '480px';
|
|
|
|
|
|
controller.style.bottom = '114px';
|
|
|
|
|
|
}
|
|
|
|
|
|
if (baselayer) {
|
|
|
|
|
|
baselayer.style.right = '480px';
|
|
|
|
|
|
baselayer.style.bottom = '20px';
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据位置获取布局数据列表
|
|
|
|
|
|
* @param data - 布局数据
|
|
|
|
|
|
* @param position - 位置
|
|
|
|
|
|
* @returns 布局数据列表
|
|
|
|
|
|
*/
|
2026-06-01 08:42:06 +08:00
|
|
|
|
const getListByPosition = (data: any, position: string) =>
|
|
|
|
|
|
data?.data?.filter((el: any) => el.position === position && el.code);
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 设置地图组件位置
|
|
|
|
|
|
* @param layoutType - 布局类型
|
2026-07-31 11:13:49 +08:00
|
|
|
|
* @param data - 布局数据({ type, data: BclDataItem[] })
|
|
|
|
|
|
* @param offset - 面板宽度 + padding + gap,默认 460(440px + 10px + 10px)
|
|
|
|
|
|
* @param bottomRowHeight - 底部行高度(如 '200px'),无底部模块时不传
|
2026-04-20 16:57:54 +08:00
|
|
|
|
*/
|
2026-06-01 08:42:06 +08:00
|
|
|
|
export const setMapLegendPos = (
|
|
|
|
|
|
layoutType: string,
|
|
|
|
|
|
data: any,
|
2026-07-31 11:13:49 +08:00
|
|
|
|
offset = 460,
|
|
|
|
|
|
bottomRowHeight?: string
|
2026-06-01 08:42:06 +08:00
|
|
|
|
) => {
|
2026-07-31 11:13:49 +08:00
|
|
|
|
const menuStateString = localStorage.getItem('menuState');
|
2026-06-01 08:42:06 +08:00
|
|
|
|
const menuState =
|
|
|
|
|
|
menuStateString !== null ? JSON.parse(menuStateString) : true;
|
|
|
|
|
|
const _theme = localStorage.getItem('ly-theme') || window.__lyConfigs?.theme;
|
2026-07-31 11:13:49 +08:00
|
|
|
|
|
|
|
|
|
|
const legend = document.querySelector('#qgc-legendtl') as HTMLElement;
|
|
|
|
|
|
const filter = document.querySelector('#map-filter-container') as HTMLElement;
|
|
|
|
|
|
const compassControl = document.querySelector('#map-compassControl') as HTMLElement;
|
|
|
|
|
|
const monitor = document.querySelector('#map-monitor') as HTMLElement;
|
|
|
|
|
|
|
2026-06-01 08:42:06 +08:00
|
|
|
|
const leftList = getListByPosition(data, 'left');
|
|
|
|
|
|
const rightList = getListByPosition(data, 'right');
|
|
|
|
|
|
const bottomList = getListByPosition(data, 'bottom');
|
2026-07-31 11:13:49 +08:00
|
|
|
|
|
|
|
|
|
|
const hasLeft = leftList?.length > 0;
|
|
|
|
|
|
const hasRight = rightList?.length > 0;
|
|
|
|
|
|
const hasBottom = bottomList?.length > 0;
|
|
|
|
|
|
|
|
|
|
|
|
const w = `${offset}px`;
|
|
|
|
|
|
const l = `${_theme === 'ly-8' ? (menuState ? 643 : 510) : offset}px`;
|
|
|
|
|
|
let b = `0px`;
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
2026-06-01 08:42:06 +08:00
|
|
|
|
if (_theme === 'ly-8') {
|
2026-07-31 11:13:49 +08:00
|
|
|
|
b = window.__mapMode === '3D' ? '200px' : `${menuState ? 200 : 50}px`;
|
2026-06-01 08:42:06 +08:00
|
|
|
|
}
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
2026-07-31 11:13:49 +08:00
|
|
|
|
// 底部偏移
|
|
|
|
|
|
// px 值:直接 + padding(10px)
|
|
|
|
|
|
// fr 值:按占比算,如 3 行各 1fr = calc((100% - 40px) / 3 + 10px)
|
|
|
|
|
|
let bottomOffset = '12px';
|
|
|
|
|
|
if (hasBottom && bottomRowHeight) {
|
|
|
|
|
|
const pxMatch = bottomRowHeight.match(/^(\d+)px$/);
|
|
|
|
|
|
if (pxMatch) {
|
|
|
|
|
|
bottomOffset = `${parseInt(pxMatch[1]) + 10}px`;
|
|
|
|
|
|
} else if (bottomRowHeight.endsWith('fr')) {
|
|
|
|
|
|
const rows = (LAYOUT_GRID_SKELETONS[layoutType]?.gridTemplateRows || '').split(' ').filter(Boolean);
|
|
|
|
|
|
const n = rows.length; // 总行数
|
|
|
|
|
|
const gaps = (n - 1) * 10; // 行间距
|
|
|
|
|
|
bottomOffset = `calc((100% - 20px - ${gaps}px) / ${n} + 10px)`;
|
2026-04-20 16:57:54 +08:00
|
|
|
|
}
|
2026-06-01 08:42:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (legend) {
|
2026-07-31 11:13:49 +08:00
|
|
|
|
legend.style.left = hasLeft ? `calc(${l} - 10px)` : b;
|
|
|
|
|
|
legend.style.bottom = bottomOffset;
|
2026-06-01 08:42:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
if (filter) {
|
2026-07-31 11:13:49 +08:00
|
|
|
|
filter.style.left = hasLeft ? l : b;
|
2026-06-01 08:42:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
if (compassControl) {
|
2026-07-31 11:13:49 +08:00
|
|
|
|
compassControl.style.left = hasLeft ? l : b;
|
2026-06-01 08:42:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
if (monitor) {
|
2026-07-31 11:13:49 +08:00
|
|
|
|
monitor.style.right = hasRight ? w : '0';
|
2026-06-01 08:42:06 +08:00
|
|
|
|
}
|
2026-08-31 14:04:06 +08:00
|
|
|
|
|
|
|
|
|
|
// 地图控制器/底图切换器:通过 store 发布位置覆盖,组件内联样式优先读取,
|
|
|
|
|
|
// 避免 JS 直写 el.style 与组件自身 :style 绑定互相覆盖(刷新后重叠问题)。
|
|
|
|
|
|
const uiStore = useUiStore();
|
|
|
|
|
|
if (hasBottom) {
|
|
|
|
|
|
// 有底部模块:有右模块时整体左移避让;两者同底(bottomOffset)
|
|
|
|
|
|
uiStore.setMapControlsPosition({
|
|
|
|
|
|
controllerRight: hasRight ? w : null,
|
|
|
|
|
|
controllerBottom: bottomOffset,
|
|
|
|
|
|
baselayerRight: hasRight ? `calc(${w} + 60px)` : null,
|
|
|
|
|
|
baselayerBottom: bottomOffset
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 无底部模块:完全回退组件自身默认样式(与非电站专题页面一致)
|
|
|
|
|
|
uiStore.setMapControlsPosition({
|
|
|
|
|
|
controllerRight: null,
|
|
|
|
|
|
controllerBottom: null,
|
|
|
|
|
|
baselayerRight: null,
|
|
|
|
|
|
baselayerBottom: null
|
|
|
|
|
|
});
|
2026-06-01 08:42:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
|
|
|
|
|
export const altitudeToZoom = (height: number) => {
|
2026-06-01 08:42:06 +08:00
|
|
|
|
const lv =
|
|
|
|
|
|
Math.round(D + (A - D) / (1 + Math.pow(Number(height) / C, B))) + 1;
|
|
|
|
|
|
return lv > -1 ? lv : 0;
|
|
|
|
|
|
};
|
2026-04-20 16:57:54 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 根据地图级别获取镜头高度
|
|
|
|
|
|
* @param {Number} zoom
|
|
|
|
|
|
*/
|
|
|
|
|
|
export const zoomToAltitude = (zoom: number) => {
|
2026-06-01 08:42:06 +08:00
|
|
|
|
return Math.round(C * Math.pow((A - D) / (zoom - D) - 1, 1 / B));
|
|
|
|
|
|
};
|
2026-04-20 16:57:54 +08:00
|
|
|
|
|
|
|
|
|
|
export const mapOutPut = (imageUrl: string) => {
|
2026-06-01 08:42:06 +08:00
|
|
|
|
const canvas = document.createElement('canvas');
|
|
|
|
|
|
const downloadElement = document.createElement('a');
|
|
|
|
|
|
const mapElem = document.getElementById('mapContainer');
|
|
|
|
|
|
if (mapElem == null) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
const context = canvas.getContext('2d')!;
|
|
|
|
|
|
canvas.width = mapElem.offsetWidth;
|
|
|
|
|
|
canvas.height = mapElem.offsetHeight;
|
|
|
|
|
|
const image = new Image();
|
|
|
|
|
|
image.src = imageUrl;
|
|
|
|
|
|
image.onload = () => {
|
|
|
|
|
|
context.drawImage(image, 0, 0);
|
|
|
|
|
|
const elem: any = document.getElementById('qgc-legendtl');
|
|
|
|
|
|
const l = elem?.style?.left === '' ? 0 : parseInt(elem?.style?.left);
|
|
|
|
|
|
if (elem) {
|
|
|
|
|
|
domtoimage
|
|
|
|
|
|
.toPng(elem, {
|
|
|
|
|
|
quality: 1.0,
|
|
|
|
|
|
width: elem.offsetWidth + (l + 24),
|
|
|
|
|
|
height: mapElem.offsetHeight - 20
|
|
|
|
|
|
})
|
|
|
|
|
|
.then((legendUrl: string) => {
|
|
|
|
|
|
const image = new Image();
|
|
|
|
|
|
image.src = legendUrl;
|
|
|
|
|
|
image.width = elem.offsetWidth;
|
|
|
|
|
|
image.onload = () => {
|
|
|
|
|
|
context.drawImage(image, 0, 0);
|
|
|
|
|
|
downloadElement.href = canvas.toDataURL('image/png');
|
|
|
|
|
|
downloadElement.download = '地图截图';
|
|
|
|
|
|
downloadElement.click();
|
|
|
|
|
|
};
|
|
|
|
|
|
})
|
2026-07-09 11:33:04 +08:00
|
|
|
|
.catch(() => {});
|
2026-06-01 08:42:06 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
downloadElement.href = canvas.toDataURL('image/png');
|
|
|
|
|
|
downloadElement.download = 'download';
|
|
|
|
|
|
downloadElement.click();
|
2026-04-20 16:57:54 +08:00
|
|
|
|
}
|
2026-06-01 08:42:06 +08:00
|
|
|
|
};
|
|
|
|
|
|
};
|