Compare commits
2 Commits
7638096eb6
...
19859bbaf0
Author | SHA1 | Date |
---|---|---|
|
19859bbaf0 | |
|
aa2b55ac01 |
|
@ -0,0 +1,85 @@
|
|||
import request from '@/utils/request'
|
||||
import { parseStrEmpty } from "@/utils/ruoyi";
|
||||
import { createUniqueString } from "@/utils/index";
|
||||
|
||||
const tempTypeList = [
|
||||
{ value: 'point', label: '点' },
|
||||
{ value: 'polyline', label: '线' },
|
||||
{ value: 'polygon', label: '面' },
|
||||
{ value: 'billboard', label: '图标' },
|
||||
{ value: 'label', label: '标签' },
|
||||
]
|
||||
const tempList = []
|
||||
|
||||
// 查询样式类型信息
|
||||
export function getStyleType() {
|
||||
return Promise.resolve(tempTypeList)
|
||||
}
|
||||
|
||||
// 查询样式列表
|
||||
export function listStyle(query) {
|
||||
const list = tempList.filter(item => {
|
||||
if(query.styleName && item.styleName.indexOf(query.styleName) === -1) {
|
||||
return false
|
||||
}
|
||||
if(query.styleType && item.styleType.indexOf(query.styleType) === -1) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
return Promise.resolve({
|
||||
rows: list,
|
||||
total: list.length,
|
||||
})
|
||||
}
|
||||
|
||||
// 查询样式详细
|
||||
export function getStyle(styleId) {
|
||||
return Promise.resolve({
|
||||
data: tempList.find(item => item.id === parseStrEmpty(styleId))
|
||||
})
|
||||
}
|
||||
|
||||
// 新增样式
|
||||
export function addStyle(data) {
|
||||
data.id = createUniqueString()
|
||||
tempList.push(data)
|
||||
return Promise.resolve({
|
||||
code: 200,
|
||||
msg: '新增成功',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改样式
|
||||
export function updateStyle(data) {
|
||||
for (const v of tempList) {
|
||||
if (v.id === data.id) {
|
||||
v.styleName = data.styleName
|
||||
v.styleType = data.styleType
|
||||
v.style = data.style
|
||||
break
|
||||
}
|
||||
}
|
||||
return Promise.resolve({
|
||||
code: 200,
|
||||
msg: '修改成功',
|
||||
})
|
||||
}
|
||||
|
||||
// 删除样式
|
||||
export function delStyle(styleId) {
|
||||
let idList = styleId
|
||||
if(typeof styleId === 'string') {
|
||||
idList = [styleId]
|
||||
}
|
||||
for (let index = tempList.length - 1; index >= 0; index--) {
|
||||
if(idList.includes(tempList[index].id)) {
|
||||
tempList.splice(index, 1)
|
||||
}
|
||||
}
|
||||
return Promise.resolve({
|
||||
code: 200,
|
||||
msg: '删除成功',
|
||||
})
|
||||
}
|
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 866 B |
|
@ -16,6 +16,7 @@ const props = defineProps({
|
|||
}
|
||||
}
|
||||
})
|
||||
const emits = defineEmits(['init'])
|
||||
let viewer = null;
|
||||
|
||||
|
||||
|
@ -92,6 +93,8 @@ const initMap = async () => {
|
|||
|
||||
// 取消左键双击
|
||||
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
|
||||
|
||||
emits('init', viewer);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import * as Cesium from "cesium";
|
||||
|
||||
const getCenterPosition = (positions) => {
|
||||
if(positions.length === 0) {
|
||||
console.warn("positions is empty");
|
||||
return Cesium.Cartesian3.ZERO;
|
||||
}
|
||||
|
||||
let maxX = Cesium.Math.toRadians(-180),
|
||||
minX = Cesium.Math.toRadians(180);
|
||||
let maxY = Cesium.Math.toRadians(-90),
|
||||
minY = Cesium.Math.toRadians(90);
|
||||
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
const cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
|
||||
if (cartographic.longitude < minX) {
|
||||
minX = cartographic.longitude;
|
||||
} else if (cartographic.longitude > maxX) {
|
||||
maxX = cartographic.longitude;
|
||||
}
|
||||
if (cartographic.latitude < minY) {
|
||||
minY = cartographic.latitude;
|
||||
} else if (cartographic.latitude > maxY) {
|
||||
maxY = cartographic.latitude;
|
||||
}
|
||||
}
|
||||
return Cesium.Cartesian3.fromRadians((minX + maxX) / 2, (minY + maxY) / 2)
|
||||
};
|
||||
|
||||
export {
|
||||
getCenterPosition
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
import * as Cesium from "cesium";
|
||||
import { getCenterPosition } from "./calcFn";
|
||||
|
||||
const createFeature = (style, position, text, layer) => {
|
||||
if (!style) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (style.properties?.type) {
|
||||
case "point":
|
||||
case "billboard":
|
||||
case "label":
|
||||
return createPointFeature(style, position, text, layer);
|
||||
case "polyline":
|
||||
return createPolylineFeature(style, position, text, layer);
|
||||
case "polygon":
|
||||
return createPolygonFeature(style, position, text, layer);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 生成点要素
|
||||
* 目前图标、标签没有额外操作,故共享该方法
|
||||
* @param {Object} style 处理后的样式对象
|
||||
* @param {Cesium.Cartesian3} position 点位置
|
||||
* @param {String} text 标签文本,可选
|
||||
* @param {Cesium.DataSource} layer 图层
|
||||
* @returns {Cesium.Entity} 点对象
|
||||
*/
|
||||
const createPointFeature = (style, position, text, layer) => {
|
||||
if (!position) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const entity = new Cesium.Entity({
|
||||
position: position,
|
||||
...cloneStyle(style),
|
||||
});
|
||||
// 添加标签文本
|
||||
// if(text !== null && text !== undefined) {
|
||||
// if(Cesium.defined(entity.label)) {
|
||||
// entity.label.text = new Cesium.ConstantProperty(text)
|
||||
// } else {
|
||||
// entity.label = new Cesium.LabelGraphics({
|
||||
// text,
|
||||
// font: '16px sans-serif',
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
if (Cesium.defined(entity.label) && text !== null && text !== undefined) {
|
||||
entity.label.text = new Cesium.ConstantProperty(text);
|
||||
}
|
||||
// 加入图层
|
||||
if (layer) {
|
||||
layer.entities.add(entity);
|
||||
}
|
||||
return entity;
|
||||
};
|
||||
|
||||
/**
|
||||
* 生成线要素
|
||||
* @param {Object} style 处理后的样式对象
|
||||
* @param {Array<Cesium.Cartesian3>} position 位置数组
|
||||
* @param {String} text 标签文本,可选
|
||||
* @param {Cesium.DataSource} layer 图层
|
||||
* @returns {Cesium.Entity} 线对象
|
||||
*/
|
||||
const createPolylineFeature = (style, position, text, layer) => {
|
||||
if (!position || position.length < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const entity = new Cesium.Entity(cloneStyle(style));
|
||||
// 添加线坐标
|
||||
if (Cesium.defined(style.polyline)) {
|
||||
entity.polyline.positions = new Cesium.ConstantProperty(
|
||||
style.properties.closed ? [...position, position[0]] : position
|
||||
);
|
||||
} else {
|
||||
entity.polyline = new Cesium.PolylineGraphics({
|
||||
positions: position,
|
||||
});
|
||||
}
|
||||
// 添加标签文本
|
||||
if (Cesium.defined(entity.label) && text !== null && text !== undefined) {
|
||||
entity.label.text = new Cesium.ConstantProperty(text)
|
||||
// 添加label坐标
|
||||
entity.position = getCenterPosition(position)
|
||||
}
|
||||
// 加入图层
|
||||
if (layer) {
|
||||
layer.entities.add(entity);
|
||||
}
|
||||
return entity;
|
||||
};
|
||||
|
||||
/**
|
||||
* 生成面要素
|
||||
* @param {Object} style 处理后的样式对象
|
||||
* @param {Array<Cesium.Cartesian3>} position 位置数组
|
||||
* @param {String} text 标签文本,可选
|
||||
* @param {Cesium.DataSource} layer 图层
|
||||
* @returns {Cesium.Entity} 面对象
|
||||
*/
|
||||
const createPolygonFeature = (style, position, text, layer) => {
|
||||
if (!position || position.length < 3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const entity = new Cesium.Entity(cloneStyle(style));
|
||||
// 添加面坐标
|
||||
if (Cesium.defined(style.polygon)) {
|
||||
entity.polygon.hierarchy = new Cesium.PolygonHierarchy(position);
|
||||
} else {
|
||||
entity.polyline = new Cesium.PolygonGraphics({
|
||||
hierarchy: new Cesium.PolygonHierarchy(position),
|
||||
});
|
||||
}
|
||||
// 添加轮廓线坐标
|
||||
// 这里消极的判断,仅当存在polyline时才添加,且必定是闭合线
|
||||
if (Cesium.defined(style.polyline)) {
|
||||
entity.polyline.positions = new Cesium.ConstantProperty([
|
||||
...position,
|
||||
position[0],
|
||||
]);
|
||||
}
|
||||
// 添加标签文本
|
||||
if (Cesium.defined(entity.label) && text !== null && text !== undefined) {
|
||||
entity.label.text = new Cesium.ConstantProperty(text)
|
||||
// 添加label坐标
|
||||
entity.position = getCenterPosition(position)
|
||||
}
|
||||
// 加入图层
|
||||
if (layer) {
|
||||
layer.entities.add(entity)
|
||||
}
|
||||
return entity;
|
||||
};
|
||||
|
||||
const cloneStyle = (style) => {
|
||||
const clone = {};
|
||||
for (let key in style) {
|
||||
console.log(key);
|
||||
if (key === "id") {
|
||||
clone[key] = style[key];
|
||||
} else if (key === "properties") {
|
||||
// 浅拷贝属性
|
||||
clone[key] = {};
|
||||
for (let prop in style[key]) {
|
||||
clone[key][prop] = style[key][prop];
|
||||
}
|
||||
} else {
|
||||
// 用cesium提供方法拷贝
|
||||
clone[key] = style[key].clone();
|
||||
}
|
||||
}
|
||||
return clone;
|
||||
};
|
||||
|
||||
export {
|
||||
createFeature,
|
||||
createPointFeature,
|
||||
createPolylineFeature,
|
||||
createPolygonFeature,
|
||||
};
|
|
@ -0,0 +1,330 @@
|
|||
import * as Cesium from 'cesium';
|
||||
|
||||
let _clampToGround = false;
|
||||
|
||||
const getStyle = (options) => {
|
||||
// 将配置项转为cesium内部类,提供复用
|
||||
const _options = {}
|
||||
// 判断类型(option提供了则套用,未提供测推断)
|
||||
if(options.type) {
|
||||
_options.type = options.type
|
||||
} else if(options.point) {
|
||||
_options.type = 'point'
|
||||
} else if(options.polygon) {
|
||||
_options.type = 'polygon'
|
||||
} else if(options.polyline) {
|
||||
_options.type = 'polyline'
|
||||
} else if(options.billboard) {
|
||||
_options.type = 'billboard'
|
||||
} else if(options.label) {
|
||||
_options.type = 'label'
|
||||
} else {
|
||||
// 什么配置都没提供,则返回空对象
|
||||
return _options
|
||||
}
|
||||
|
||||
// 转通用配置
|
||||
const common = parseCommonOptions(_options.type, options.common);
|
||||
// 属性配置项
|
||||
const property = options.property || {};
|
||||
property.type = _options.type;
|
||||
|
||||
switch (_options.type) {
|
||||
case 'point':
|
||||
return parsePointOptions(options, common, property)
|
||||
case 'polyline':
|
||||
return parsePolylineOptions(options, common, property)
|
||||
case 'polygon':
|
||||
return parsePolygonOptions(options, common, property)
|
||||
case 'billboard':
|
||||
return parseBillboardOptions(options, common, property)
|
||||
case 'label':
|
||||
return parseLabelOptions(options, common, property)
|
||||
default:
|
||||
console.warn('不支持的样式类型:', _options.type);
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
// 解析通用配置
|
||||
const parseCommonOptions = (type, options) => {
|
||||
const _options = {}
|
||||
if(!options) {
|
||||
return _options
|
||||
}
|
||||
// 贴地
|
||||
if(options.clampToGround) {
|
||||
_clampToGround = true;
|
||||
}
|
||||
// 按视距缩放
|
||||
// 线和面没有按视距缩放
|
||||
if(options.scaleByDistance && type !== 'polyline' && type !== 'polygon') {
|
||||
_options.scaleByDistance = new Cesium.NearFarScalar(
|
||||
options.scaleNear,
|
||||
options.scaleNearValue,
|
||||
options.scaleFar,
|
||||
options.scaleFarValue
|
||||
);
|
||||
}
|
||||
return _options
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析点相关配置为对象
|
||||
* @param {Object} options 总配置项
|
||||
* @param {Object} common 通用配置对象
|
||||
* @param {Object} property 属性配置对象
|
||||
* @returns 点样式对象
|
||||
*/
|
||||
const parsePointOptions = (options, common, property) => {
|
||||
const style = {
|
||||
point: createPointByOptions(options.point, common),
|
||||
properties: property || {}
|
||||
}
|
||||
// 添加图标、标签
|
||||
if(options.billboard) {
|
||||
style.billboard = createBillboardByOptions(options.billboard, common)
|
||||
}
|
||||
if(options.label) {
|
||||
style.label = createLabelByOptions(options.label, common)
|
||||
}
|
||||
return style
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析点配置项
|
||||
* @param {Object} options 点配置项
|
||||
* @param {Object} common 通用配置对象
|
||||
* @returns cesium点对象
|
||||
*/
|
||||
const createPointByOptions = (options, common) => {
|
||||
if(!options) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const _options = {
|
||||
pixelSize: parseFloat(options.pixelSize) || 10,
|
||||
color: Cesium.Color.fromCssColorString(options.color) || Cesium.Color.WHITE,
|
||||
...common
|
||||
}
|
||||
if(options.showOutline) {
|
||||
_options.outlineWidth = parseFloat(options.outlineWidth) || 1
|
||||
_options.outlineColor = Cesium.Color.fromCssColorString(options.outlineColor) || Cesium.Color.BLACK
|
||||
}
|
||||
if(_clampToGround) {
|
||||
_options.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND
|
||||
}
|
||||
return new Cesium.PointGraphics(_options)
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析线相关配置为对象
|
||||
* @param {Object} options 总配置项
|
||||
* @param {Object} common 通用配置对象
|
||||
* @param {Object} property 属性配置对象
|
||||
* @returns 线样式对象
|
||||
*/
|
||||
const parsePolylineOptions = (options, common, property) => {
|
||||
const style = {
|
||||
polyline: createPolylineByOptions(options.polyline, common),
|
||||
properties: property || {}
|
||||
}
|
||||
// 添加闭合属性
|
||||
if(options.polyline.closed) {
|
||||
property.closed = true
|
||||
}
|
||||
// 添加标签
|
||||
if(options.label) {
|
||||
style.label = createLabelByOptions(options.label, common)
|
||||
}
|
||||
return style
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析线配置项
|
||||
* @param {Object} options 线配置项
|
||||
* @param {Object} common 通用配置对象
|
||||
* @param {Object} property 属性配置对象
|
||||
* @returns cesium线对象
|
||||
*/
|
||||
const createPolylineByOptions = (options, common) => {
|
||||
if(!options) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const _options = {
|
||||
width: parseFloat(options.width) || 1,
|
||||
material: Cesium.Color.fromCssColorString(options.color) || Cesium.Color.WHITE,
|
||||
...common
|
||||
}
|
||||
if(_clampToGround) {
|
||||
_options.clampToGround = true
|
||||
}
|
||||
return new Cesium.PolylineGraphics(_options)
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析面相关配置为对象
|
||||
* @param {Object} options 总配置项
|
||||
* @param {Object} common 通用配置对象
|
||||
* @param {Object} property 属性配置对象
|
||||
* @returns 面样式对象
|
||||
*/
|
||||
const parsePolygonOptions = (options, common, property) => {
|
||||
const style = {
|
||||
polygon: createPolygonByOptions(options.polygon, common),
|
||||
properties: property || {}
|
||||
}
|
||||
// 添加面的轮廓线
|
||||
if(options.polygon.showOutline) {
|
||||
property.closed = true
|
||||
style.polyline = createPolygonOutlineByOptions(options.polygon, common)
|
||||
}
|
||||
// 添加标签
|
||||
if(options.label) {
|
||||
style.label = createLabelByOptions(options.label, common)
|
||||
}
|
||||
return style
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析面的轮廓线配置项
|
||||
* 因面的自带相关属性不支持贴地形,所以生成cesium线对象
|
||||
* @param {Object} options 面配置项
|
||||
* @param {Object} common 通用配置对象
|
||||
* @returns cesium线对象
|
||||
*/
|
||||
const createPolygonOutlineByOptions = (options, common) => {
|
||||
if(!options) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const _options = {
|
||||
width: parseFloat(options.outlineWidth) ?? 1,
|
||||
material: Cesium.Color.fromCssColorString(options.outlineColor) || Cesium.Color.BLACK,
|
||||
...common
|
||||
}
|
||||
if(_clampToGround) {
|
||||
_options.clampToGround = true
|
||||
}
|
||||
return new Cesium.PolylineGraphics(_options)
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析面配置项
|
||||
* @param {Object} options 面配置项
|
||||
* @param {Object} common 通用配置对象
|
||||
* @returns cesium面对象
|
||||
*/
|
||||
const createPolygonByOptions = (options, common) => {
|
||||
if(!options) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const _options = {
|
||||
material: Cesium.Color.fromCssColorString(options.color) || Cesium.Color.WHITE,
|
||||
...common
|
||||
}
|
||||
if(_clampToGround) {
|
||||
_options.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND
|
||||
}
|
||||
return new Cesium.PolygonGraphics(_options)
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析图标相关配置为对象
|
||||
* @param {Object} options 总配置项
|
||||
* @param {Object} common 通用配置对象
|
||||
* @param {Object} property 属性配置对象
|
||||
* @returns 图标样式对象
|
||||
*/
|
||||
const parseBillboardOptions = (options, common, property) => {
|
||||
const style = {
|
||||
billboard: createBillboardByOptions(options.billboard, common),
|
||||
properties: property || {}
|
||||
}
|
||||
// 添加标签
|
||||
if(options.label) {
|
||||
style.label = createLabelByOptions(options.label, common)
|
||||
}
|
||||
return style
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析图标配置项
|
||||
* @param {Object} options 图标配置项
|
||||
* @param {Object} common 通用配置对象
|
||||
* @returns cesium图标对象
|
||||
*/
|
||||
const createBillboardByOptions = (options, common) => {
|
||||
if(!options) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const _options = {
|
||||
image: options.image,
|
||||
scale: parseFloat(options.scale) ?? 1,
|
||||
rotation: Cesium.Math.toRadians(parseFloat(options.rotation) || 0),
|
||||
horizontalOrigin: parseInt(options.horizontalOrigin) ?? Cesium.HorizontalOrigin.CENTER,
|
||||
verticalOrigin: parseInt(options.verticalOrigin) ?? Cesium.VerticalOrigin.BOTTOM,
|
||||
pixelOffset: new Cesium.Cartesian2(parseFloat(options.horizontalOffset) || 0, parseFloat(options.verticalOffset) || 0),
|
||||
...common
|
||||
}
|
||||
if(_clampToGround) {
|
||||
_options.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND
|
||||
}
|
||||
return new Cesium.BillboardGraphics(_options)
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析标签相关配置为对象
|
||||
* @param {Object} options 总配置项
|
||||
* @param {Object} common 通用配置对象
|
||||
* @param {Object} property 属性配置对象
|
||||
* @returns 标签样式对象
|
||||
*/
|
||||
const parseLabelOptions = (options, common, property) => {
|
||||
return {
|
||||
label: createLabelByOptions(options.label, common),
|
||||
properties: property || {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析标签配置项
|
||||
* @param {Object} options 标签配置项
|
||||
* @param {Object} common 通用配置对象
|
||||
* @returns cesium标签对象
|
||||
*/
|
||||
const createLabelByOptions = (options, common) => {
|
||||
if(!options) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const _options = {
|
||||
font: `${options.font ?? 16}px sans-serif`,
|
||||
fillColor: Cesium.Color.fromCssColorString(options.fillColor) || Cesium.Color.WHITE,
|
||||
horizontalOrigin: parseInt(options.horizontalOrigin) ?? Cesium.HorizontalOrigin.CENTER,
|
||||
verticalOrigin: parseInt(options.verticalOrigin) ?? Cesium.VerticalOrigin.BOTTOM,
|
||||
pixelOffset: new Cesium.Cartesian2(parseFloat(options.horizontalOffset) ?? 0, parseFloat(options.verticalOffset) ?? 0),
|
||||
...common
|
||||
}
|
||||
if(options.showOutline) {
|
||||
_options.style = Cesium.LabelStyle.FILL_AND_OUTLINE
|
||||
_options.outlineWidth = parseFloat(options.outlineWidth) || 1
|
||||
_options.outlineColor = Cesium.Color.fromCssColorString(options.outlineColor) || Cesium.Color.BLACK
|
||||
}
|
||||
if(options.showBackground) {
|
||||
_options.showBackground = true
|
||||
_options.backgroundColor = Cesium.Color.fromCssColorString(options.backgroundColor) || new Cesium.Color(0.165, 0.165, 0.165, 0.8)
|
||||
_options.backgroundPadding = new Cesium.Cartesian2(parseFloat(options.horizontalPadding) ?? 7, parseFloat(options.verticalPadding) ?? 5)
|
||||
}
|
||||
if(_clampToGround) {
|
||||
_options.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND
|
||||
}
|
||||
return new Cesium.LabelGraphics(_options)
|
||||
}
|
||||
|
||||
export {
|
||||
getStyle
|
||||
}
|
|
@ -99,6 +99,12 @@ export const constantRoutes = [
|
|||
component: () => import('@/views/gisManagement/configSetting/index.vue'),
|
||||
name: 'configSetting',
|
||||
meta: { title: '地图配置' }
|
||||
},
|
||||
{
|
||||
path: 'configStyle',
|
||||
component: () => import('@/views/gisManagement/configStyle/index.vue'),
|
||||
name: 'configStyle',
|
||||
meta: { title: '样式配置' }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
<template>
|
||||
<el-dialog v-model="show" title="选择图标" width="600px">
|
||||
<!-- <el-button type="primary">上传本地图片</el-button> -->
|
||||
<div v-loading="loading">
|
||||
<el-upload action="#" :auto-upload="false" :show-file-list="false" :on-change="handleFileChange"
|
||||
accept="image/*">
|
||||
<el-button type="primary">上传本地图片</el-button>
|
||||
</el-upload>
|
||||
<div class="icon-container">
|
||||
<div :class="{active: icon === selectedItem}" class="icon-item" v-for="(icon, index) in icons" :key="index" @click="selectIcon(icon)">
|
||||
<el-image style="width: 48px; height: 48px" :src="icon" fit="contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm" :disabled="!selectedItem">
|
||||
确定
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import analysisAroundIcon from '@/assets/icons/example/analysis_around.png'
|
||||
import analysisCoordinationLocationIcon from '@/assets/icons/example/analysis_coordination_location.png'
|
||||
import analysisMapLocationIcon from '@/assets/icons/example/analysis_map_location.png'
|
||||
import analysisSandboxIcon from '@/assets/icons/example/analysis_sandbox.png'
|
||||
import analysisSpreadIcon from '@/assets/icons/example/analysis_spread.png'
|
||||
import checkPointIcon from '@/assets/icons/example/check_point.png'
|
||||
import sandboxExplosiveIcon from '@/assets/icons/example/sandbox_explosive.png'
|
||||
import sandboxFireIcon from '@/assets/icons/example/sandbox_fire.png'
|
||||
import sandboxFirefighterIcon from '@/assets/icons/example/sandbox_firefighter.png'
|
||||
import sandboxFirepointIcon from '@/assets/icons/example/sandbox_firepoint.png'
|
||||
import sandboxFlameIcon from '@/assets/icons/example/sandbox_flame.png'
|
||||
import sandboxTrappedIcon from '@/assets/icons/example/sandbox_trapped.png'
|
||||
import sandboxWaterIcon from '@/assets/icons/example/sandbox_water.png'
|
||||
|
||||
const show = defineModel()
|
||||
const props = defineProps({
|
||||
current: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
const emits = defineEmits(['update:current'])
|
||||
|
||||
// const icons = ref([
|
||||
// { url: analysisAroundIcon },
|
||||
// { url: analysisCoordinationLocationIcon },
|
||||
// { url: analysisMapLocationIcon },
|
||||
// { url: analysisSandboxIcon },
|
||||
// { url: analysisSpreadIcon },
|
||||
// { url: checkPointIcon },
|
||||
// { url: sandboxExplosiveIcon },
|
||||
// { url: sandboxFireIcon },
|
||||
// { url: sandboxFirefighterIcon },
|
||||
// { url: sandboxFirepointIcon },
|
||||
// { url: sandboxFlameIcon },
|
||||
// { url: sandboxTrappedIcon },
|
||||
// { url: sandboxWaterIcon }
|
||||
// ])
|
||||
const icons = ref([
|
||||
analysisAroundIcon,
|
||||
analysisCoordinationLocationIcon,
|
||||
analysisMapLocationIcon,
|
||||
analysisSandboxIcon,
|
||||
analysisSpreadIcon,
|
||||
checkPointIcon,
|
||||
sandboxExplosiveIcon,
|
||||
sandboxFireIcon,
|
||||
sandboxFirefighterIcon,
|
||||
sandboxFirepointIcon,
|
||||
sandboxFlameIcon,
|
||||
sandboxTrappedIcon,
|
||||
sandboxWaterIcon
|
||||
])
|
||||
const loading = ref(false)
|
||||
const selectedItem = ref(props.current)
|
||||
|
||||
/* 上传图片 */
|
||||
const handleFileChange = (uploadFile) => {
|
||||
loading.value = true;
|
||||
const file = uploadFile.raw;
|
||||
if (!file) return;
|
||||
|
||||
// 检查文件类型
|
||||
if (!file.type.startsWith('image/')) {
|
||||
ElMessage.error('只能上传图片文件!');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查文件大小 (可选)
|
||||
// const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
// if (!isLt2M) {
|
||||
// ElMessage.error('图片文件大小不能超过 2MB!');
|
||||
// return;
|
||||
// }
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => {
|
||||
const base64String = reader.result;
|
||||
if(icons.value.includes(base64String)) {
|
||||
ElMessage.error('该图片已存在,请选择其他图片!');
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
icons.value.push(base64String);
|
||||
loading.value = false;
|
||||
};
|
||||
reader.onerror = () => {
|
||||
ElMessage.error('读取图片时出错!');
|
||||
loading.value = false;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
/* 图片点击 */
|
||||
const selectIcon = (icon) => {
|
||||
selectedItem.value = icon
|
||||
}
|
||||
|
||||
/* 确认 */
|
||||
const handleConfirm = () => {
|
||||
emits('update:current', selectedItem.value)
|
||||
show.value = false
|
||||
}
|
||||
|
||||
/* 取消 */
|
||||
const handleCancel = () => {
|
||||
selectedItem.value = props.current
|
||||
show.value = false
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.icon-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
border-left: 1px solid var(--el-border-color);
|
||||
|
||||
.icon-item {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
// background-color: #f0f0f0;
|
||||
border-right: 1px solid var(--el-border-color);
|
||||
border-bottom: 1px solid var(--el-border-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
|
||||
&:nth-child(-n+10) {
|
||||
border-top: 1px solid var(--el-border-color);
|
||||
}
|
||||
&:hover {
|
||||
// background-color: #e0e0e0;
|
||||
background-color: var(--el-border-color-extra-light);
|
||||
color: var(--brand-color-light);
|
||||
}
|
||||
&.active {
|
||||
background-color: var(--el-color-primary-light-6);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,234 @@
|
|||
<template>
|
||||
<el-dialog v-model="dialogVisible" title="选择图标/图片" width="600px" @close="handleCancel">
|
||||
<div class="image-library-content">
|
||||
<!-- 上传本地图片 -->
|
||||
<div class="upload-area">
|
||||
<el-upload action="#" :auto-upload="false" :show-file-list="false" :on-change="handleFileChange"
|
||||
accept="image/*">
|
||||
<el-button type="primary">上传本地图片</el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
|
||||
<!-- 图标/图片列表 -->
|
||||
<div class="item-list">
|
||||
<div v-for="item in items" :key="item.id" :class="['item', { 'is-selected': selectedItem?.id === item.id }]"
|
||||
@click="selectItem(item)">
|
||||
<template v-if="item.type === 'system' && item.component">
|
||||
<!-- Element Plus Icon -->
|
||||
<el-icon :size="30">
|
||||
<component :is="item.component" />
|
||||
</el-icon>
|
||||
</template>
|
||||
<template v-else-if="item.type === 'system' && item.display">
|
||||
<!-- System Image URL -->
|
||||
<img :src="item.display" alt="system image" class="item-image" />
|
||||
</template>
|
||||
<template v-else-if="item.type === 'local' && item.display">
|
||||
<!-- Local Base64 Image -->
|
||||
<img :src="item.display" alt="local image" class="item-image" />
|
||||
</template>
|
||||
<div v-else class="item-placeholder">无预览</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm" :disabled="!selectedItem">
|
||||
确定
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, onMounted } from 'vue';
|
||||
import { ElDialog, ElButton, ElUpload, ElIcon, ElMessage } from 'element-plus';
|
||||
// 导入 Element Plus Icons (按需导入或全局注册)
|
||||
// 如果是全局注册,则不需要在这里导入
|
||||
// 如果是按需导入,需要导入你用到的图标组件
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue';
|
||||
|
||||
// 定义 props
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
initialValue: {
|
||||
type: String, // 传入的当前选中图片的值 (URL 或 Base64)
|
||||
default: null
|
||||
}
|
||||
});
|
||||
|
||||
// 定义 emits
|
||||
const emit = defineEmits(['update:visible', 'confirm']);
|
||||
|
||||
// 弹窗可见性
|
||||
const dialogVisible = ref(props.visible);
|
||||
|
||||
// 图标/图片列表数据
|
||||
const items = ref([]);
|
||||
|
||||
// 当前选中的项
|
||||
const selectedItem = ref(null);
|
||||
|
||||
// 默认系统图标和图片
|
||||
const defaultSystemItems = [
|
||||
// Element Plus Icons (示例)
|
||||
{ id: 'icon-star', type: 'system', display: 'Star', value: 'ElIconStarFilled', component: 'ElIconStarFilled' },
|
||||
{ id: 'icon-picture', type: 'system', display: 'Picture', value: 'ElIconPicture', component: 'ElIconPicture' },
|
||||
{ id: 'icon-folder', type: 'system', display: 'Folder', value: 'ElIconFolder', component: 'ElIconFolder' },
|
||||
{ id: 'icon-setting', type: 'system', display: 'Setting', value: 'ElIconSetting', component: 'ElIconSetting' },
|
||||
{ id: 'icon-user', type: 'system', display: 'User', value: 'ElIconUser', component: 'ElIconUser' },
|
||||
// System Images (示例 URLs)
|
||||
{ id: 'img-placeholder-1', type: 'system', display: 'https://via.placeholder.com/50x50?text=Img1', value: 'https://via.placeholder.com/50x50?text=Img1' },
|
||||
{ id: 'img-placeholder-2', type: 'system', display: 'https://via.placeholder.com/50x50?text=Img2', value: 'https://via.placeholder.com/50x50?text=Img2' },
|
||||
];
|
||||
|
||||
// 加载默认系统项
|
||||
// onMounted(() => {
|
||||
// items.value = [...defaultSystemItems];
|
||||
// });
|
||||
|
||||
// 监听 visible prop 变化,同步弹窗状态并处理回显
|
||||
// watch(() => props.visible, (newVal) => {
|
||||
// dialogVisible.value = newVal;
|
||||
// if (newVal) {
|
||||
// // 弹窗打开时,根据 initialValue 查找并选中对应的项
|
||||
// selectedItem.value = items.value.find(item => item.value === props.initialValue) || null;
|
||||
// } else {
|
||||
// // 弹窗关闭时,重置选中状态
|
||||
// selectedItem.value = null;
|
||||
// }
|
||||
// });
|
||||
|
||||
// 处理文件上传变化
|
||||
const handleFileChange = (uploadFile) => {
|
||||
const file = uploadFile.raw;
|
||||
if (!file) return;
|
||||
|
||||
// 检查文件类型
|
||||
if (!file.type.startsWith('image/')) {
|
||||
ElMessage.error('只能上传图片文件!');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查文件大小 (可选)
|
||||
// const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
// if (!isLt2M) {
|
||||
// ElMessage.error('图片文件大小不能超过 2MB!');
|
||||
// return;
|
||||
// }
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => {
|
||||
const base64String = reader.result;
|
||||
const newItem = {
|
||||
id: `local-${Date.now()}-${Math.random().toString(16).slice(2)}`, // 确保唯一ID
|
||||
type: 'local',
|
||||
display: base64String, // Base64 用于显示
|
||||
value: base64String // Base64 用于返回
|
||||
};
|
||||
items.value.push(newItem);
|
||||
// 自动选中新上传的图片 (可选)
|
||||
// selectedItem.value = newItem;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
};
|
||||
|
||||
// 选中一个项
|
||||
const selectItem = (item) => {
|
||||
selectedItem.value = item;
|
||||
};
|
||||
|
||||
// 处理确定按钮点击
|
||||
const handleConfirm = () => {
|
||||
if (selectedItem.value) {
|
||||
// 返回选中项的 value (URL 或 Base64)
|
||||
emit('confirm', selectedItem.value.value);
|
||||
// 关闭弹窗
|
||||
emit('update:visible', false);
|
||||
}
|
||||
};
|
||||
|
||||
// 处理取消按钮点击或弹窗关闭
|
||||
const handleCancel = () => {
|
||||
emit('update:visible', false);
|
||||
};
|
||||
|
||||
// 将 Element Plus Icons 暴露给模板使用 (如果按需导入)
|
||||
// 如果是全局注册,则不需要这一步
|
||||
const icons = ElementPlusIconsVue;
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.image-library-content {
|
||||
padding: 0 20px 20px 20px;
|
||||
/* 调整内边距 */
|
||||
}
|
||||
|
||||
.upload-area {
|
||||
margin-bottom: 20px;
|
||||
text-align: right;
|
||||
/* 让上传按钮靠右 */
|
||||
}
|
||||
|
||||
.item-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
/* 项之间的间距 */
|
||||
max-height: 300px;
|
||||
/* 限制列表高度并添加滚动条 */
|
||||
overflow-y: auto;
|
||||
padding-right: 10px;
|
||||
/* 为滚动条留出空间 */
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 60px;
|
||||
/* 项的固定宽度 */
|
||||
height: 60px;
|
||||
/* 项的固定高度 */
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.3s;
|
||||
overflow: hidden;
|
||||
/* 防止图片溢出 */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.item:hover {
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
.item.is-selected {
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 0 5px rgba(64, 158, 255, 0.5);
|
||||
}
|
||||
|
||||
.item-image {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
/* 保持图片比例 */
|
||||
}
|
||||
|
||||
.item-placeholder {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 调整 Element Plus Icon 的样式 */
|
||||
.item .el-icon {
|
||||
font-size: 30px;
|
||||
/* 确保图标大小合适 */
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,155 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-card style="margin-bottom: 12px;" shadow="always" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px">
|
||||
<el-form-item label="样式名称" prop="styleName">
|
||||
<el-input v-model="queryParams.styleName" placeholder="请输入样式名称" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="样式类型" prop="styleType">
|
||||
<el-select clearable v-model="queryParams.styleType" style="width: 200px" placeholder="请选择样式类型">
|
||||
<el-option v-for="type in styleTypeList" :key="type.value" :label="type.label" :value="type.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card shadow="always" class="list-table-section">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="formDialogRef.show()">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="formDialogRef.show(ids[0])">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
<el-table v-loading="loading" :data="styleList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="样式名称" align="center" prop="styleName" />
|
||||
<el-table-column label="样式类型" align="center" prop="styleType">
|
||||
<template #default="{ row }">
|
||||
<!-- <el-tag type="primary" v-for="(type, index) in row.type.split(',')" :key="index">
|
||||
{{ styleTypeList.find(item => item.id === type) }}
|
||||
</el-tag> -->
|
||||
<el-tag v-for="(dict, index) in styleTypeList"
|
||||
v-show="row.styleType === dict.value" :key="index">{{ dict.label }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="描述信息" align="center" prop="description" />
|
||||
<el-table-column label="操作" width="300" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="{ row }">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="formDialogRef.show(row.id)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(row)"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
<div class="page-wrap">
|
||||
<pagination class="list-page" v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</div>
|
||||
<style-dialog ref="formDialogRef" @refresh="getList()" />
|
||||
</template>
|
||||
|
||||
<script setup name="configStyle">
|
||||
import { getStyleType, listStyle, delStyle } from "@/api/gisManagement/configStyle"
|
||||
import styleDialog from "./styleDialog.vue"
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const styleTypeList = ref([])
|
||||
const styleList = ref([])
|
||||
const loading = ref(true)
|
||||
const showSearch = ref(true)
|
||||
const ids = ref([])
|
||||
const single = ref(true)
|
||||
const multiple = ref(true)
|
||||
const total = ref(0)
|
||||
|
||||
const formDialogRef = ref()
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
styleName: '',
|
||||
styleType: null
|
||||
})
|
||||
|
||||
/* 初始化 */
|
||||
function init() {
|
||||
// 获取样式类型
|
||||
getStyleType().then(response => {
|
||||
styleTypeList.value = response
|
||||
})
|
||||
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 查询用户信息列表 */
|
||||
function getList() {
|
||||
loading.value = true
|
||||
listStyle(queryParams.value).then(response => {
|
||||
styleList.value = response.rows
|
||||
total.value = response.total
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
queryParams.value.pageNum = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
proxy.resetForm("queryRef")
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
// 多选框选中数据
|
||||
function handleSelectionChange(selection) {
|
||||
ids.value = selection.map(item => item.id)
|
||||
single.value = selection.length != 1
|
||||
multiple.value = !selection.length
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
function handleDelete(row) {
|
||||
const _userIds = row.id || ids.value
|
||||
proxy.$modal.confirm('是否确认删除勾选的数据项?').then(function () {
|
||||
return delStyle(_userIds)
|
||||
}).then(() => {
|
||||
getList()
|
||||
proxy.$modal.msgSuccess("删除成功")
|
||||
}).catch(() => { })
|
||||
}
|
||||
|
||||
init()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-container {
|
||||
position: relative;
|
||||
height: calc(100vh - 84px);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.list-table-section {
|
||||
flex: auto;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,728 @@
|
|||
<template>
|
||||
<el-dialog v-model="showDialog" :title="title" width="800px" destroy-on-close>
|
||||
<div class="form-wrapper">
|
||||
<div class="base-container">
|
||||
<el-form class="base-info" :model="form" ref="formRef" :label-width="labelWidth">
|
||||
<el-form-item label="样式名称" prop="styleName">
|
||||
<el-input v-model="form.styleName" placeholder="请输入样式名称" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="样式类型" prop="styleType">
|
||||
<el-select clearable v-model="form.styleType" placeholder="请选择样式类型" @change="handleTypeChange">
|
||||
<el-option v-for="type in styleTypeList" :key="type.value" :label="type.label" :value="type.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="description">
|
||||
<el-input v-model="form.description" type="textarea" :autosize="{ minRows: 4, maxRows: 4 }" resize="none"
|
||||
placeholder="请输入描述信息"></el-input>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12" v-if="form.styleType === 'point'">
|
||||
<el-form-item label="显示图标" prop="showBillboard">
|
||||
<el-switch v-model="showBillboard" @change="refreshMap" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" v-if="['point', 'polyline', 'polygon', 'billboard'].includes(form.styleType)">
|
||||
<el-form-item label="显示标签" prop="showLabel">
|
||||
<el-switch v-model="showLabel" @change="refreshMap" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div class="map-preview">
|
||||
<cesium-map :options="mapOptions" @init="initMap" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="sub-container">
|
||||
<!-- 点样式 -->
|
||||
<el-form v-if="showPoint" :model="formPoint" ref="formPointRef" :label-width="labelWidth">
|
||||
<el-divider content-position="left" class="style-title">点样式配置</el-divider>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="像素大小" prop="pixelSize">
|
||||
<!-- <el-input v-model="form.styleName" placeholder="请输入像素大小" clearable></el-input> -->
|
||||
<el-input-number v-model="formPoint.pixelSize" :min="1" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="颜色" prop="color">
|
||||
<el-color-picker v-model="formPoint.color" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="轮廓线" prop="showOutline">
|
||||
<el-switch v-model="formPoint.showOutline" />
|
||||
</el-form-item>
|
||||
<el-row v-if="formPoint.showOutline" :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="宽度" prop="outlineWidth">
|
||||
<!-- <el-input v-model="form.styleName" placeholder="请输入像素大小" clearable></el-input> -->
|
||||
<el-input-number v-model="formPoint.outlineWidth" :min="1" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="颜色" prop="outlineColor">
|
||||
<el-color-picker v-model="formPoint.outlineColor" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<!-- 线样式 -->
|
||||
<el-form v-if="showPolyline" :model="formPolyline" ref="formPolylineRef" :label-width="labelWidth">
|
||||
<el-divider content-position="left" class="style-title">线样式配置</el-divider>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="宽度" prop="width">
|
||||
<!-- <el-input v-model="form.styleName" placeholder="请输入像素大小" clearable></el-input> -->
|
||||
<el-input-number v-model="formPolyline.width" :min="1" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="颜色" prop="color">
|
||||
<el-color-picker v-model="formPolyline.color" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="闭合" prop="closed">
|
||||
<el-switch v-model="formPolyline.closed" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- 面样式 -->
|
||||
<el-form v-if="showPolygon" :model="formPolygon" ref="formPolygonRef" :label-width="labelWidth">
|
||||
<el-divider content-position="left" class="style-title">面样式配置</el-divider>
|
||||
<el-form-item label="填充颜色" prop="color">
|
||||
<el-color-picker v-model="formPolygon.color" />
|
||||
</el-form-item>
|
||||
<el-form-item label="轮廓线" prop="showOutline">
|
||||
<el-switch v-model="formPolygon.showOutline" />
|
||||
</el-form-item>
|
||||
<el-row v-if="formPolygon.showOutline" :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="宽度" prop="outlineWidth">
|
||||
<!-- <el-input v-model="form.styleName" placeholder="请输入像素大小" clearable></el-input> -->
|
||||
<el-input-number v-model="formPolygon.outlineWidth" :min="1" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="颜色" prop="outlineColor">
|
||||
<el-color-picker v-model="formPolygon.outlineColor" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<!-- 图标样式 -->
|
||||
<el-form v-if="showBillboard" :model="formBillboard" ref="formBillboardRef" :label-width="labelWidth">
|
||||
<el-divider content-position="left" class="style-title">图标样式配置</el-divider>
|
||||
<el-form-item label="图片" prop="image">
|
||||
<el-image class="style-billboard-image" :src="formBillboard.image" fit="contain"
|
||||
@click="handleIconSelect" />
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="缩放" prop="scale">
|
||||
<el-slider v-model="formBillboard.scale" :max="5" :min="0.1" :step="0.1" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="旋转" prop="rotation">
|
||||
<el-input-number v-model="formBillboard.rotation" :min="0" :max="360" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="横向定位" prop="horizontalOrigin">
|
||||
<el-select v-model="formBillboard.horizontalOrigin" placeholder="请选择横向定位">
|
||||
<el-option v-for="item in horizontalOriginTypeList" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="纵向定位" prop="verticalOrigin">
|
||||
<el-select v-model="formBillboard.verticalOrigin" placeholder="请选择纵向定位">
|
||||
<el-option v-for="item in verticalOriginTypeList" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="横向偏移" prop="horizontalOffset">
|
||||
<el-input-number v-model="formBillboard.horizontalOffset" style="width: calc(100% - 60px);" />
|
||||
<span style="margin-left: 8px;">(右为正)</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="纵向偏移" prop="verticalOffset">
|
||||
<el-input-number v-model="formBillboard.verticalOffset" style="width: calc(100% - 60px);" />
|
||||
<span style="margin-left: 8px;">(下为正)</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<!-- 标签样式 -->
|
||||
<el-form v-if="showLabel" :model="formLabel" ref="formLabelRef" :label-width="labelWidth">
|
||||
<el-divider content-position="left" class="style-title">标签样式配置</el-divider>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="字号" prop="font">
|
||||
<el-input-number v-model="formLabel.font" :min="12" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="颜色" prop="fillColor">
|
||||
<el-color-picker v-model="formLabel.fillColor" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="轮廓线" prop="showOutline">
|
||||
<el-switch v-model="formLabel.showOutline" />
|
||||
</el-form-item>
|
||||
<el-row v-if="formLabel.showOutline" :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="宽度" prop="outlineWidth">
|
||||
<el-input-number v-model="formLabel.outlineWidth" :min="1" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="颜色" prop="outlineColor">
|
||||
<el-color-picker v-model="formLabel.outlineColor" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="背景" prop="showBackground">
|
||||
<el-switch v-model="formLabel.showBackground" />
|
||||
</el-form-item>
|
||||
<el-row v-if="formLabel.showBackground" :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="横向内边距" prop="horizontalPadding">
|
||||
<el-input-number v-model="formLabel.horizontalPadding" :min="0" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="纵向内边距" prop="verticalPadding">
|
||||
<el-input-number v-model="formLabel.verticalPadding" :min="0" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="颜色" prop="backgroundColor">
|
||||
<el-color-picker v-model="formLabel.backgroundColor" show-alpha />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="横向定位" prop="horizontalOrigin">
|
||||
<el-select v-model="formLabel.horizontalOrigin" placeholder="请选择横向定位">
|
||||
<el-option v-for="item in horizontalOriginTypeList" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="纵向定位" prop="verticalOrigin">
|
||||
<el-select v-model="formLabel.verticalOrigin" placeholder="请选择纵向定位">
|
||||
<el-option v-for="item in verticalOriginTypeList" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="横向偏移" prop="horizontalOffset">
|
||||
<el-input-number v-model="formLabel.horizontalOffset" style="width: calc(100% - 60px);" />
|
||||
<span style="margin-left: 8px;">(右为正)</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="纵向偏移" prop="verticalOffset">
|
||||
<el-input-number v-model="formLabel.verticalOffset" style="width: calc(100% - 60px);" />
|
||||
<span style="margin-left: 8px;">(下为正)</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<!-- 通用样式 -->
|
||||
<el-form :model="formCommon" ref="formCommonRef" :label-width="labelWidth">
|
||||
<el-divider content-position="left" class="style-title">通用样式配置</el-divider>
|
||||
<el-form-item label="贴地" prop="clampToGround">
|
||||
<el-switch v-model="formCommon.clampToGround" />
|
||||
</el-form-item>
|
||||
<div v-if="['point', 'billboard', 'label'].includes(form.styleType)">
|
||||
<el-form-item label="按视距缩放" prop="scaleByDistance">
|
||||
<el-switch v-model="formCommon.scaleByDistance" />
|
||||
</el-form-item>
|
||||
<el-row v-if="formCommon.scaleByDistance" :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="缩放近视距" prop="scaleNear">
|
||||
<el-input-number v-model="formCommon.scaleNear" :min="0" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="缩放比例" prop="scaleNearValue">
|
||||
<el-input-number v-model="formCommon.scaleNearValue" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="formCommon.scaleByDistance" :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="缩放远视距" prop="scaleFar">
|
||||
<el-input-number v-model="formCommon.scaleFar" :min="1" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="缩放比例" prop="scaleFarValue">
|
||||
<el-input-number v-model="formCommon.scaleFarValue" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<icon-dialog ref="iconDialog" v-model:current="formBillboard.image" v-model="showIconDialog" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">保存</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="styleDialog">
|
||||
import * as Cesium from 'cesium'
|
||||
|
||||
import CesiumMap from '@/components/CesiumMap/index.vue';
|
||||
import { getStyle } from "@/components/CesiumMap/utils/styleFn";
|
||||
import { createFeature } from "@/components/CesiumMap/utils/layerFn";
|
||||
import IconDialog from "./iconDialog.vue";
|
||||
|
||||
import { getStyleType, getStyle as getStyleApi, addStyle, updateStyle } from "@/api/gisManagement/configStyle"
|
||||
|
||||
import checkPointIcon from '@/assets/icons/example/check_point.png'
|
||||
|
||||
const emits = defineEmits(['refresh'])
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const showDialog = ref(false)
|
||||
const title = ref('');
|
||||
const labelWidth = '85px'
|
||||
let viewer = null
|
||||
let entity = null
|
||||
const defaultPoint = [102, 25]
|
||||
const defaultPosition = Cesium.Cartesian3.fromDegrees(...defaultPoint)
|
||||
const defaultPolyline = Cesium.Cartesian3.fromDegreesArray([102.1, 24.9, 102.1, 25.1, 101.9, 24.9, 101.9, 25.2])
|
||||
const defaultPolygon = Cesium.Cartesian3.fromDegreesArray([102.1, 24.9, 102.1, 25.1, 101.9, 25.1, 101.9, 24.9])
|
||||
const mapOptions = {
|
||||
setView: {
|
||||
x: defaultPoint[0],
|
||||
y: defaultPoint[1],
|
||||
z: 5000,
|
||||
heading: 0,
|
||||
pitch: -90,
|
||||
roll: 0
|
||||
}
|
||||
}
|
||||
const styleTypeList = ref([])
|
||||
const horizontalOriginTypeList = ref([
|
||||
{ label: '左', value: 1 },
|
||||
{ label: '中', value: 0 },
|
||||
{ label: '右', value: -1 }
|
||||
])
|
||||
const verticalOriginTypeList = ref([
|
||||
{ label: '上', value: -1 },
|
||||
{ label: '中', value: 0 },
|
||||
{ label: '下', value: 1 }
|
||||
])
|
||||
const form = ref({
|
||||
id: null,
|
||||
styleName: '',
|
||||
styleType: [],
|
||||
description: '',
|
||||
config: '',
|
||||
})
|
||||
const showPoint = ref(false)
|
||||
const formPoint = ref({
|
||||
pixelSize: 10,
|
||||
color: '#ffffff',
|
||||
showOutline: false,
|
||||
outlineWidth: 1,
|
||||
outlineColor: '#000000',
|
||||
})
|
||||
const showPolyline = ref(false)
|
||||
const formPolyline = ref({
|
||||
width: 1,
|
||||
color: '#ffffff',
|
||||
closed: false,
|
||||
})
|
||||
const showPolygon = ref(false)
|
||||
const formPolygon = ref({
|
||||
color: '#ffffff',
|
||||
showOutline: false,
|
||||
outlineWidth: 1,
|
||||
outlineColor: '#000000',
|
||||
})
|
||||
const showBillboard = ref(false)
|
||||
const formBillboard = ref({
|
||||
image: checkPointIcon,
|
||||
scale: 1,
|
||||
rotation: 0,
|
||||
horizontalOrigin: 0,
|
||||
verticalOrigin: 1,
|
||||
horizontalOffset: 0,
|
||||
verticalOffset: 0,
|
||||
})
|
||||
const showIconDialog = ref(false)
|
||||
const showLabel = ref(false)
|
||||
const formLabel = ref({
|
||||
font: 12,
|
||||
fillColor: '#ffffff',
|
||||
showOutline: false,
|
||||
outlineWidth: 1,
|
||||
outlineColor: '#000000',
|
||||
showBackground: false,
|
||||
backgroundColor: 'rgba(42, 42, 42, 0.8)',
|
||||
horizontalPadding: 0,
|
||||
verticalPadding: 0,
|
||||
horizontalOrigin: 0,
|
||||
verticalOrigin: 1,
|
||||
horizontalOffset: 0,
|
||||
verticalOffset: 0,
|
||||
})
|
||||
const formCommon = ref({
|
||||
clampToGround: true,
|
||||
scaleByDistance: false,
|
||||
scaleNear: 0,
|
||||
scaleNearValue: 0,
|
||||
scaleFar: 1,
|
||||
scaleFarValue: 0,
|
||||
})
|
||||
|
||||
/**
|
||||
* 打开弹窗的方法
|
||||
* @param id 样式id
|
||||
*/
|
||||
const show = async (id) => {
|
||||
reset()
|
||||
if (id) {
|
||||
title.value = '修改样式信息'
|
||||
getStyleApi(id).then(res => {
|
||||
// const data = response.data
|
||||
// form.value.styleName = data.styleName
|
||||
// form.value.styleType = data.styleType
|
||||
// form.value.description = data.description
|
||||
form.value = res.data
|
||||
const config = JSON.parse(form.value.config)
|
||||
if (config.point) {
|
||||
showPoint.value = true
|
||||
formPoint.value = config.point
|
||||
}
|
||||
if (config.polyline) {
|
||||
showPolyline.value = true
|
||||
formPolyline.value = config.polyline
|
||||
}
|
||||
if (config.polygon) {
|
||||
showPolygon.value = true
|
||||
formPolygon.value = config.polygon
|
||||
}
|
||||
if (config.billboard) {
|
||||
showBillboard.value = true
|
||||
formBillboard.value = config.billboard
|
||||
}
|
||||
if (config.label) {
|
||||
showLabel.value = true
|
||||
formLabel.value = config.label
|
||||
}
|
||||
formCommon.value = config.common
|
||||
})
|
||||
} else {
|
||||
title.value = '新增样式信息'
|
||||
form.value.id = null
|
||||
}
|
||||
// 获取样式类型
|
||||
getStyleType().then(response => {
|
||||
styleTypeList.value = response
|
||||
})
|
||||
|
||||
showDialog.value = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化地图
|
||||
*/
|
||||
const initMap = (viewerInstance) => {
|
||||
// 初始化地图变量
|
||||
viewer = viewerInstance
|
||||
// entity = viewer.entities.add({
|
||||
// id: 'stylePreview',
|
||||
// position: defaultPosition, // 默认位置
|
||||
// })
|
||||
// 设置不能平移
|
||||
viewer.camera.lookAt(
|
||||
defaultPosition, // 设置初始位置
|
||||
new Cesium.HeadingPitchRange(Cesium.Math.toRadians(0), Cesium.Math.toRadians(-90), 5000) // 设置初始视角
|
||||
);
|
||||
refreshMap()
|
||||
}
|
||||
|
||||
/**
|
||||
* 样式类型改变, 切换配置项显示
|
||||
* @param {string} val 类型值
|
||||
*/
|
||||
const handleTypeChange = (val) => {
|
||||
if (val === 'point') {
|
||||
showPoint.value = true
|
||||
showPolyline.value = false
|
||||
showPolygon.value = false
|
||||
showBillboard.value = false
|
||||
showLabel.value = false
|
||||
} else if (val === 'polyline') {
|
||||
showPoint.value = false
|
||||
showPolyline.value = true
|
||||
showPolygon.value = false
|
||||
showBillboard.value = false
|
||||
showLabel.value = false
|
||||
} else if (val === 'polygon') {
|
||||
showPoint.value = false
|
||||
showPolyline.value = false
|
||||
showPolygon.value = true
|
||||
showBillboard.value = false
|
||||
showLabel.value = false
|
||||
} else if (val === 'billboard') {
|
||||
showPoint.value = false
|
||||
showPolyline.value = false
|
||||
showPolygon.value = false
|
||||
showBillboard.value = true
|
||||
showLabel.value = false
|
||||
} else if (val === 'label') {
|
||||
showPoint.value = false
|
||||
showPolyline.value = false
|
||||
showPolygon.value = false
|
||||
showBillboard.value = false
|
||||
showLabel.value = true
|
||||
} else {
|
||||
// 隐藏所有样式配置项
|
||||
showPoint.value = false
|
||||
showPolyline.value = false
|
||||
showPolygon.value = false
|
||||
showBillboard.value = false
|
||||
showLabel.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开图标选择对话框
|
||||
*/
|
||||
const handleIconSelect = () => {
|
||||
showIconDialog.value = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新地图
|
||||
* 更新样式后触发
|
||||
*/
|
||||
const refreshMap = () => {
|
||||
if(!viewer) {
|
||||
return
|
||||
}
|
||||
|
||||
const options = {
|
||||
type: form.value.styleType,
|
||||
}
|
||||
if (showPoint.value) options.point = formPoint.value
|
||||
if (showPolyline.value) options.polyline = formPolyline.value
|
||||
if (showPolygon.value) options.polygon = formPolygon.value
|
||||
if (showBillboard.value) options.billboard = formBillboard.value
|
||||
if (showLabel.value) options.label = formLabel.value
|
||||
options.common = formCommon.value
|
||||
console.log('更新样式配置:', JSON.stringify(options))
|
||||
form.value.config = JSON.stringify(options)
|
||||
|
||||
if (entity) {
|
||||
viewer.entities.remove(entity)
|
||||
}
|
||||
const style = getStyle(options)
|
||||
style.id = 'stylePreview'
|
||||
let position = defaultPosition
|
||||
if (style.properties?.type === 'polyline') {
|
||||
position = defaultPolyline
|
||||
} else if (style.properties?.type === 'polygon') {
|
||||
position = defaultPolygon
|
||||
}
|
||||
entity = createFeature(style, position, '测试')
|
||||
if (entity) {
|
||||
viewer.entities.add(entity)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const reset = () => {
|
||||
viewer = null
|
||||
entity = null
|
||||
form.value = {
|
||||
id: null,
|
||||
styleName: '',
|
||||
styleType: [],
|
||||
description: '',
|
||||
config: '',
|
||||
}
|
||||
showPoint.value = false
|
||||
formPoint.value = {
|
||||
pixelSize: 10,
|
||||
color: '#ffffff',
|
||||
showOutline: false,
|
||||
outlineWidth: 1,
|
||||
outlineColor: '#000000',
|
||||
}
|
||||
showPolyline.value = false
|
||||
formPolyline.value = {
|
||||
width: 1,
|
||||
color: '#ffffff',
|
||||
closed: false,
|
||||
}
|
||||
showPolygon.value = false
|
||||
formPolygon.value = {
|
||||
color: '#ffffff',
|
||||
showOutline: false,
|
||||
outlineWidth: 1,
|
||||
outlineColor: '#000000',
|
||||
}
|
||||
showBillboard.value = false
|
||||
formBillboard.value = {
|
||||
image: checkPointIcon,
|
||||
scale: 1,
|
||||
rotation: 0,
|
||||
horizontalOrigin: 0,
|
||||
verticalOrigin: 1,
|
||||
horizontalOffset: 0,
|
||||
verticalOffset: 0,
|
||||
}
|
||||
showLabel.value = false
|
||||
formLabel.value = {
|
||||
font: 12,
|
||||
fillColor: '#ffffff',
|
||||
showOutline: false,
|
||||
outlineWidth: 1,
|
||||
outlineColor: '#000000',
|
||||
showBackground: false,
|
||||
backgroundColor: 'rgba(42, 42, 42, 0.8)',
|
||||
horizontalPadding: 0,
|
||||
verticalPadding: 0,
|
||||
horizontalOrigin: 0,
|
||||
verticalOrigin: 1,
|
||||
horizontalOffset: 0,
|
||||
verticalOffset: 0,
|
||||
}
|
||||
formCommon.value = {
|
||||
clampToGround: true,
|
||||
scaleByDistance: false,
|
||||
scaleNear: 0,
|
||||
scaleNearValue: 0,
|
||||
scaleFar: 1,
|
||||
scaleFarValue: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 确定
|
||||
*/
|
||||
const handleConfirm = () => {
|
||||
// proxy.$refs["styleRef"].validate(valid => {
|
||||
// if (valid) {
|
||||
// if (form.value.userId != null) {
|
||||
// updateUser(form.value).then(response => {
|
||||
// proxy.$modal.msgSuccess("修改成功")
|
||||
// open.value = false
|
||||
// getList()
|
||||
// })
|
||||
// } else {
|
||||
// addUser(form.value).then(response => {
|
||||
// proxy.$modal.msgSuccess("新增成功")
|
||||
// open.value = false
|
||||
// getList()
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
|
||||
proxy.$refs["formRef"].validate(valid => {
|
||||
if (valid) {
|
||||
if (form.value.id) {
|
||||
updateStyle(form.value).then(response => {
|
||||
proxy.$modal.msgSuccess("修改成功")
|
||||
emits('refresh', response)
|
||||
showDialog.value = false
|
||||
})
|
||||
} else {
|
||||
addStyle(form.value).then(response => {
|
||||
proxy.$modal.msgSuccess("新增成功")
|
||||
emits('refresh', response)
|
||||
showDialog.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消
|
||||
*/
|
||||
const handleCancel = () => {
|
||||
showDialog.value = false
|
||||
}
|
||||
|
||||
watch(form.value.styleType, (val) => {
|
||||
if (val === 'polyline' || val === 'polygon') {
|
||||
formCommon.value.scaleByDistance = false
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => [form.value.styleType, formPoint, formPolyline, formPolygon, formBillboard, formLabel, formCommon], refreshMap, {
|
||||
deep: true
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.base-container {
|
||||
display: flex;
|
||||
|
||||
.base-info {
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.map-preview {
|
||||
width: 40%;
|
||||
min-width: 400px;
|
||||
height: 250px;
|
||||
margin-left: 20px;
|
||||
border: 1px solid var(--el-border-color);
|
||||
}
|
||||
}
|
||||
|
||||
.sub-container {
|
||||
margin-top: 12px;
|
||||
max-height: calc(70vh - 290px);
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.style-title {
|
||||
margin: 32px 0;
|
||||
}
|
||||
|
||||
.style-billboard-image {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border: 1px solid var(--el-border-color);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|