Files
sdk4.0/src/Tools/index.js
2025-07-03 13:54:01 +08:00

1074 lines
33 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @name: index
* @author: Administrator
* @date: 2022-06-09 16:46
* @descriptionindex
* @update: 2022-06-09 16:46
*/
import md5 from 'js-md5'
import { Proj } from './proj'
import { open as projConvertOpen, close as projConvertClose } from './projConvert'
import { open as projectionConvertOpen, close as projectionConvertClose } from './projectionConvert'
import { setActiveViewer, closeRotateAround, closeViewFollow } from '../Global/global'
class Tools {
/**
* @constructor
* @desc 工具类
* */
constructor(sdk, options) {
this.sdk = sdk
if (this.sdk) {
this.name_map = this.sdk.proj.name_map
this.epsg_map = this.sdk.proj.epsg_map
this.convert = this.sdk.proj.convert
this.getAllProjection = this.sdk.proj.getAllProjection
this.projectionIsExists = this.sdk.proj.projectionIsExists
this.degreesToDMS = this.sdk.proj.degreesToDMS
this.dmsToDecimal = this.sdk.proj.dmsToDecimal
}
this.options = { ...options }
}
get POST() {
return 'POST'
}
get GET() {
return 'GET'
}
static _md5(text) {
return md5(text).toUpperCase()
}
/**
* @description 将角度转换为弧度
* @method degreesToRadians
* @param degrees {number} 弧度制
* @return radians {number}
* @memberOf Tools
* @example let radians = tool.degreesToRadians(20)
* */
degreesToRadians(degrees) {
return turf.degreesToRadians(Number(degrees)) // 1.0471975511965976
}
/**
* @description 将弧度转换为角度
* @method radiansToDegrees
* @param radians {number} 弧度制
* @return degrees {number}
* @memberOf Tools
* @example let degrees = tool.radiansToDegrees(2)
* */
radiansToDegrees(radians) {
return turf.radiansToDegrees(Number(radians)) // 1.0471975511965976
}
/**
* @desc 随机字符串
* @function randomString
* @memberOf extra
* @param {number} [e=32] 字符串长度
* @returns {string} str 字符串
* @memberOf Tools
* @example let strings=tool.randomString()
* */
randomString(e) {
/* e = e || 32
var t = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678',
a = t.length,
n = ''
for (let i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a))*/
return Cesium.createGuid()
}
getSourceRootPath() {
let sdkName = 'YJEarth.min.js'
let scripts = document.querySelectorAll('script')
let prefix = ''
scripts.forEach((item) => {
if (item.src && item.src.indexOf(sdkName) > -1) {
let arr = item.src.split('/')
arr.pop()
prefix = arr.join('/')
}
})
return prefix
}
/**@description 笛卡尔坐标转经纬度
* @method cartesian3Towgs84
* @param cartesian {Cesium.Cartesian3} 笛卡尔坐标
* @param viewer
* @param cartesian.x {number}
* @param cartesian.y {number}
* @param cartesian.z {number}
* @memberOf Tools
* @return {object} wgs84 返回wgs84坐标
* */
cartesian3Towgs84(cartesian, viewer) {
var ellipsoid = viewer.scene.globe.ellipsoid
var cartesian3 = new Cesium.Cartesian3(
cartesian.x,
cartesian.y,
cartesian.z
)
var cartographic = ellipsoid.cartesianToCartographic(cartesian3)
var lat = Cesium.Math.toDegrees(cartographic.latitude)
var lng = Cesium.Math.toDegrees(cartographic.longitude)
var alt = cartographic.height < 0 ? 0 : cartographic.height
return {
lng: lng,
lat: lat,
alt: alt,
}
}
/**
* @desc 计算多线段长度
* @method computeDistance
* @memberOf Tools
*@param positions {Array.<{lng:number, lat:number,alt:number}>}坐标数组
* @param [fractionDigits=2] 保留小数点位数
* @param [ground=true] 是否贴地
* */
computeDistance(positions = [], fractionDigits = 2, ground = true) {
if (positions.length < 2) {
return 0
} else {
let length = 0
if (ground) {
let lineString = []
positions.forEach((item) => {
lineString.push([item.lng, item.lat, item.alt])
})
let line = turf.lineString(lineString)
length = turf.length(line) * 1000
}
else {
for (let i = 0; i < positions.length - 1; i++) {
const position1 = Cesium.Cartesian3.fromDegrees(positions[i].lng, positions[i].lat, positions[i].alt);
const position2 = Cesium.Cartesian3.fromDegrees(positions[i + 1].lng, positions[i + 1].lat, positions[i + 1].alt);
const distance = Cesium.Cartesian3.distance(position1, position2);
length = length + distance
}
}
return length.toFixed(fractionDigits)
}
}
/**@description 计算多边形面积
* @method computeArea
* @memberOf Tools
* @param positions {Array.<{lng:number, lat:number,alt:number}>}
* @param [fractionDigits=2] {number} 精确到小数点多少位
* @return {number} 面积
* */
computeArea(positions, fractionDigits = 2) {
if (positions.length < 3) {
return 0
} else {
let p = []
positions.forEach((item) => {
p.push([item.lng, item.lat])
})
p.push(p[0])
let polygon = turf.polygon([p])
let triangles = turf.tesselate(polygon);
return Number(turf.area(triangles).toFixed(fractionDigits))
}
}
computeSignedArea(viewer, path) {
let _this = this
let fromDegreesArray = []
let fromDegreesArray2 = []
for (let i = 0; i < path.length; i++) {
fromDegreesArray.push(path[i].lng, path[i].lat)
fromDegreesArray2.push([path[i].lng, path[i].lat])
}
let line = turf.lineString(fromDegreesArray2);
let bbox = turf.bbox(line);
let longRadians = Cesium.Math.toRadians(bbox[2] - bbox[0]);
let latRadians = Cesium.Math.toRadians(bbox[3] - bbox[1]);
let granularity
if (longRadians > latRadians) {
granularity = longRadians / 10
}
else {
granularity = latRadians / 10
}
// let granularity = Math.PI / Math.pow(2, 11);
// granularity = granularity / 1250;
let polygonGeometry = new Cesium.PolygonGeometry.fromPositions({
positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
vertexFormat: Cesium.PerInstanceColorAppearance.FLAT_VERTEX_FORMAT,
granularity: granularity,
});
//创建自定义平面几何体
let geom = new Cesium.PolygonGeometry.createGeometry(polygonGeometry);
if (!geom || !geom.attributes || !geom.attributes.position) {
return 0
}
const indices = geom.indices; //获取顶点索引数据
const positions = geom.attributes.position.values;
function returnPosition(position, index) {
let pos3 = new Cesium.Cartesian3(
positions[index * 3],
positions[index * 3 + 1],
positions[index * 3 + 2]
);
let position1 = viewer.scene.clampToHeight(pos3) || pos3
// let pos84 = await _this.cartesian3Towgs84(position1, viewer)
// let height = 0
// try {
// let position2 = await Cesium.sampleTerrainMostDetailed(
// viewer.scene.terrainProvider,
// [Cesium.Cartographic.fromCartesian(pos3)]
// )
// height = position2[0].height
// } catch (error) {
// height = 0
// }
// if (height > pos84.alt) {
// pos84.alt = height
// }
return position1
}
let area = 0
for (let index = 0; index < indices.length; index += 3) {
const pos0 = returnPosition(positions, indices[index]);
const pos1 = returnPosition(positions, indices[index + 1]);
const pos2 = returnPosition(positions, indices[index + 2]);
// let entity = viewer.entities.add({
// name: "三角面",
// polygon: {
// hierarchy: [pos0, pos1, pos2],
// perPositionHeight: true,
// material: Cesium.Color.fromRandom(),
// outline: true,
// outlineColor: Cesium.Color.BLACK,
// },
// });
let v0 = Cesium.Cartesian3.subtract(pos0, pos1, new Cesium.Cartesian3())
let v1 = Cesium.Cartesian3.subtract(pos2, pos1, new Cesium.Cartesian3())
let cross = Cesium.Cartesian3.cross(v0, v1, v0);
area = (area + Cesium.Cartesian3.magnitude(cross) * 0.5)
}
return Number(area.toFixed(2))
}
/**
* @desc 创建圆
*@method createCircle
* @param point {object} 圆心坐标
* @param point.lng {number} 经度
* @param point.lat {number} 纬度
* @param radius {number} 半径 单位:米
* @param [options]
* @param [options.steps=360] {number} 段数
* @memberOf Tools
* */
createCircle(point, radius = 1, options = { steps: 360 }) {
if (Number(radius) <= 0) {
radius = 0.01
}
var center = [Number(point.lng), Number(point.lat)]
let coordinates = turf.circle(center, radius / 1000, options).geometry
.coordinates[0]
let positions = []
coordinates.forEach((item) => {
positions = positions.concat(item)
})
return positions
}
/**
* @desc 创建椭圆
*@method createEllipse
* @param point {object} 圆心坐标
* @param point.lng {number} 经度
* @param point.lat {number} 纬度
* @param [options]
* @param [options.granularity=0.1] {number} 椭圆上点之间的角度
* @param [options.semiMinorAxis=10] {number} 短半轴长度 单位:米
* @param [options.semiMajorAxis=20] {number} 长半轴长度 单位:米
* @param [options.bearing=0] {number} 椭圆旋转角度 单位:米
* @memberOf Tools
* */
createEllipse(point, options = { granularity: 0.1, semiMinorAxis: 10, semiMajorAxis: 20, bearing: 0, height: 0 }) {
if (!options.granularity) {
options.granularity = 0.1
}
if (!options.height) {
options.height = 0
}
if (!options.semiMinorAxis) {
options.semiMinorAxis = 0.00001
}
if (!options.semiMajorAxis) {
options.semiMajorAxis = 0.00001
}
let ellipseGeometry = new Cesium.EllipseOutlineGeometry({
center: Cesium.Cartesian3.fromDegrees(Number(point.lng), Number(point.lat)),
semiMajorAxis: Number(options.semiMajorAxis),
semiMinorAxis: Number(options.semiMinorAxis),
height: Number(options.height),
granularity: Cesium.Math.toRadians(options.granularity),
rotation: Cesium.Math.toRadians(options.bearing),
})
let ellipse = Cesium.EllipseOutlineGeometry.createGeometry(ellipseGeometry)
if (!ellipse || !ellipse.attributes || !ellipse.attributes.position) {
return []
}
const ellipsePositions = ellipse.attributes.position.values;
let positions = []
for (let i = 0; i < ellipsePositions.length; i += 3) {
let pos = new Cesium.Cartesian3(
ellipsePositions[i],
ellipsePositions[i + 1],
ellipsePositions[i + 2]
)
positions.push(pos)
}
return positions
}
/*计算2点的恒相线夹角*/
rhumbBearing(p1, p2) {
var point1 = turf.point([p1.lng, p1.lat],);
var point2 = turf.point([p2.lng, p2.lat],);
return turf.rhumbBearing(point1, point2);
}
computeCenter(positions = []) {
let arr = []
positions.forEach((item) => {
arr.push(turf.point([item.lng, item.lat]))
})
var features = turf.featureCollection(arr)
var coordinates = turf.center(features).geometry.coordinates
return {
lng: coordinates[0],
lat: coordinates[1],
}
}
//计算2点的中心点
computeMidpoint(point1, point2) {
let p1 = turf.point([point1.lng, point1.lat])
let p2 = turf.point([point2.lng, point2.lat])
var center = turf.midpoint(p1, p2).geometry.coordinates
return { lng: center[0], lat: center[1] }
}
//计算
computeAttackArrow(positions = []) {
return this.computeArrow(positions, 0)
}
//计算钳击箭头
computePincerArrow(positions = []) {
return this.computeArrow(positions)
}
//计算攻击箭头
computeArrow(positions = [], type = 1) {
if (positions.length < 3) {
return []
} else {
var lnglatArr = []
// if(positions.every(pos => Number(pos.lng) >= 0) || positions.every(pos => Number(pos.lng) <= 0)) {
// for (var i = 0; i < positions.length; i++) {
// lnglatArr.push([positions[i].lng, positions[i].lat])
// }
// }
// else {
// for (var i = 0; i < positions.length; i++) {
// if(positions[i].lng<0) {
// lnglatArr.push([positions[i].lng+360, positions[i].lat])
// }
// else {
// lnglatArr.push([positions[i].lng, positions[i].lat])
// }
// }
// }
for (var i = 0; i < positions.length; i++) {
lnglatArr.push([positions[i].lng, positions[i].lat])
}
var res
if (type) {
res = xp.algorithm.doubleArrow(lnglatArr)
} else {
res = xp.algorithm.tailedAttackArrow(lnglatArr)
}
var index = JSON.stringify(res.polygonalPoint).indexOf('null')
var returnData = []
if (index === -1) returnData = res.polygonalPoint
return returnData
}
}
// 计算集结地
computeAssemble(positions = [], is84 = false) {
if (positions.length < 2) {
return []
} else {
let points = positions.length;
let pnts = new Array();
positions.forEach((item) => {
pnts.push([item.lng, item.lat]);
});
//console.log("pnts6666",pnts);
// pnts.push(tailPoint);
// pnts.push(headerPoint);
if (pnts.length === 2) {
let mid = P.PlotUtils.mid(pnts[0], pnts[1])
//let d = utils.MathDistance(pnts[0], mid) / 0.9
let d = P.PlotUtils.distance(pnts[0], mid) / 0.9
//console.log("d",d);
let pnt = P.PlotUtils.getThirdPoint(pnts[0], mid, P.Constants.HALF_PI, d, true)
pnts = [pnts[0], pnt, pnts[1]];
//console.log("pnt",pnt);
//createPoint(Cesium.Cartesian3.fromDegrees(pnt[0], pnt[1]));
}
let mid = P.PlotUtils.mid(pnts[0], pnts[2])
pnts.push(mid, pnts[0], pnts[1])
let [normals, pnt1, pnt2, pnt3, result, result2] = [[], undefined, undefined, undefined, [], []]
for (let i = 0; i < pnts.length - 2; i++) {
pnt1 = pnts[i]
pnt2 = pnts[i + 1]
pnt3 = pnts[i + 2]
let normalPoints = P.PlotUtils.getBisectorNormals(0.4, pnt1, pnt2, pnt3)
normals = normals.concat(normalPoints)
}
let count = normals.length
normals = [normals[count - 1]].concat(normals.slice(0, count - 1))
for (let i = 0; i < pnts.length - 2; i++) {
pnt1 = pnts[i]
pnt2 = pnts[i + 1]
result = result.concat([...pnt1])
for (let t = 0; t <= P.Constants.FITTING_COUNT; t++) {
let pnt = P.PlotUtils.getCubicValue(t / P.Constants.FITTING_COUNT, pnt1, normals[i * 2], normals[i * 2 + 1], pnt2)
result = result.concat([...pnt])
}
result = result.concat([...pnt2])
}
if (is84) {
return result
}
else {
return Cesium.Cartesian3.fromDegreesArray(result)
}
}
}
// 计算直线箭头
computeStraightArrow(positions = [], is84 = false) {
if (positions.length < 2) {
return []
}
let point1 = [positions[0].lng, positions[0].lat]
let point2 = [positions[1].lng, positions[1].lat]
if (positions[0].lng === positions[1].lng && positions[0].lat === positions[1].lat) {
if (is84) {
return [positions[0], positions[0], positions[0]]
}
else {
let cartesian3 = Cesium.Cartesian3.fromDegrees(positions[0].lng, positions[0].lat)
return [cartesian3, cartesian3, cartesian3]
}
}
let lnglatArr = []
for (let i = 0; i < positions.length; i++) {
lnglatArr.push([positions[i].lng, positions[i].lat])
}
let res
res = xp.algorithm.fineArrow(point1, point2)
if (is84) {
let pos84 = []
for (let i = 0; i < res.length; i++) {
let pos = this.cartesian3Towgs84(res[i], this.sdk.viewer)
pos84.push(pos.lng, pos.lat)
}
return pos84
}
return res
}
getMaterial(color = '#2ab0c2', type = 0) {
let material = ''
switch (Number(type)) {
case 1: //虚线
material = new Cesium.PolylineDashMaterialProperty({
color: Cesium.Color.fromCssColorString(color),
dashLength: 10, //短划线长度
})
break
case 2: //泛光
material = new Cesium.PolylineGlowMaterialProperty({
glowPower: 0.2,
color: Cesium.Color.fromCssColorString(color),
})
break
default:
material = Cesium.Color.fromCssColorString(color)
break
}
return material
}
/*创建直箭头图片*/
create_arrow1_picture(color) {
let canvas = new fabric.Canvas('canvas')
canvas.width = 150
canvas.height = 75
let w_offset = 35
let h_offset = 20
let fill = color
let polygon = new fabric.Polygon(
[
{ x: canvas.width, y: canvas.height / 2 }, //箭头右边顶点
{ x: canvas.width - w_offset, y: canvas.height }, //顺时针
{ x: canvas.width - w_offset, y: canvas.height - h_offset }, //
{ x: canvas.width / 2, y: canvas.height - h_offset }, //
{ x: canvas.width / 2, y: h_offset }, //
{ x: canvas.width - w_offset, y: h_offset }, //
{ x: canvas.width - w_offset, y: 0 }, //
],
{
fill,
}
)
canvas.add(polygon)
return canvas.toDataURL()
}
/*创建箭头图片*/
create_arrow2_picture(color) {
let canvas = new fabric.Canvas('canvas')
canvas.width = 75
canvas.height = 75
let w_offset1 = 35
let w_offset2 = 40
let fill = color
let polygon = new fabric.Polygon(
[
{ x: canvas.width, y: canvas.height / 2 },
{ x: canvas.width - w_offset1, y: canvas.height },
{ x: canvas.width - w_offset1 - w_offset2, y: canvas.height },
{ x: canvas.width - w_offset2, y: canvas.height / 2 },
{ x: canvas.width - w_offset1 - w_offset2, y: 0 },
{ x: canvas.width - w_offset1, y: 0 },
],
{
fill,
}
)
canvas.add(polygon)
return canvas.toDataURL()
}
sampleHeightMostDetailed(positions) {
let cartesians = []
positions.forEach((item) => {
cartesians.push(new Cesium.Cartographic.fromDegrees(item.lng, item.lat))
})
return this.sdk.viewer.scene.sampleHeightMostDetailed(cartesians)
}
flyHome(duration = 3) {
setActiveViewer(0)
closeRotateAround(this.sdk)
closeViewFollow(this.sdk)
if (this.sdk.viewer.CAMERA_DEFAULT_VIEW_RECTANGLE) {
let destination = this.sdk.viewer.CAMERA_DEFAULT_VIEW_RECTANGLE.destination
let orientation = this.sdk.viewer.CAMERA_DEFAULT_VIEW_RECTANGLE.orientation
this.sdk.viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(destination.lng, destination.lat, destination.alt),
orientation: {
heading: Cesium.Math.toRadians(orientation.heading || 0),
pitch: Cesium.Math.toRadians(orientation.pitch || 0),
roll: Cesium.Math.toRadians(orientation.roll || 0)
},
duration: duration
})
}
else {
this.sdk.viewer.camera.flyHome(duration)
}
}
/**
* @description 设置拾取操作启停
* @method setPickStatus
* @param [status=true] {boolean}
* @memberOf Tools
* */
setPickStatus(status = true) {
// YJ.getEarth().interaction.picking.enabled = status
}
/**
* @description 创建点缓冲区 返回缓冲区坐标
* @method create_point_buffer
* @param point {object} 坐标参数
* @param [radius=5] {number} 缓冲距离 (单位:米)
* @param option
* @param point.lng {number} 经度
* @param point.lat {number} 纬度
* @memberOf Tools
* @returns {Array} 返回缓冲区坐标数组
*/
create_point_buffer(point, radius = 5, option = { steps: 10 }) {
let p = turf.point([Number(point.lng), Number(point.lat)])
let buffered = turf.buffer(p, Number(radius) / 1000, option)
return buffered.geometry.coordinates
}
/**
* @description 创建线缓冲区 返回缓冲区坐标
* @method create_line_buffer
* @param points {Array.<lng:"",lat:"">} 坐标参数
* @param [radius=5] {number} 缓冲距离 (单位:米)
* @memberOf Tools
* @returns {Array} 返回缓冲区坐标数组
* @example let points = [{lng:"",lat:""},{lng:"",lat:""},{lng:"",lat:""}]
* let radius = 10
* let area_buffer = sdk.create_line_buffer(points,radius)
* */
create_line_buffer(points, radius = 5) {
if (points.length === 1) {
return this.create_point_buffer(points[0], radius)
} else if (points.length === 0) {
return false
} else {
let arr = []
points.forEach((point) => {
arr.push([Number(point.lng), Number(point.lat)])
})
let line = turf.lineString(arr)
let buffered = turf.buffer(line, Number(radius) / 1000)
return buffered.geometry.coordinates
}
}
/**
* @description 创建面缓冲区 返回缓冲区坐标
* @method create_area_buffer
* @param points {Array.<lng:"",lat:"">} 坐标参数
* @param [radius=5] {number} 缓冲距离 (单位:米)
* @memberOf Tools
* @returns {Array} 返回缓冲区坐标数组
* @example let points = [{lng:"",lat:""},{lng:"",lat:""},{lng:"",lat:""}]
* let radius = 10
* let area_buffer = sdk.create_area_buffer(points,radius)
* */
create_area_buffer(points, radius = 5) {
if (points.length === 1) {
return this.create_point_buffer(points[0], radius)
} else if (points.length === 0) {
return false
} else if (points.length === 2) {
return this.create_line_buffer(points, radius)
} else {
let arr = []
points.forEach((point) => {
arr.push([Number(point.lng), Number(point.lat)])
})
arr.push(arr[0])
let poly = turf.polygon([arr])
let buffered = turf.buffer(poly, Number(radius) / 1000)
return buffered.geometry.coordinates
}
}
/**
* @desc 计算多点范围
* @method cal_envelope
* @memberOf Tools
* */
cal_envelope(points = []) {
if (points.length < 2) {
console.error('坐标数量不能少于2个')
} else {
let arr = []
points.forEach((p) => {
arr.push(turf.point([p.lng, p.lat]))
})
let features = turf.featureCollection(arr)
return turf.envelope(features).geometry.coordinates[0]
}
}
/**
* @desc 按指定距离分段
* @method chunkLine
* @param positions {Array}
* @param meters
* @memberOf Tools
* */
chunkLine(positions = [], meters = 1000) {
if (positions.length < 2) {
return []
} else {
let arr = []
positions.forEach((it) => {
arr.push([it.lng, it.lat])
})
let line = turf.lineString(arr)
let chunk = turf.lineChunk(line, meters / 1000)
let __map = new Map()
chunk.features.forEach((value) => {
value.geometry.coordinates.forEach((value1) => {
let key = value1.join(',')
let val = { lng: value1[0], lat: value1[1] }
__map.set(key, val)
})
})
return chunk.features
}
}
/**
* @desc 标注以sinx的半个周期的形式弹跳
* */
billboardAnimation(viewer, { id, offset = 10, times = 3 }) {
let entity = viewer.entities.getById(id)
if (entity) {
let pi = Math.PI
let tt = 60
let of = pi / tt
let h = 0
let src_p = this.cartesian3Towgs84(entity.position.getValue(), viewer)
// let height = src_p.alt
// entity.position = new Cesium.CallbackProperty(() => {
// let height = offset * Math.sin(h) + src_p.alt
// h += of
// return Cesium.Cartesian3.fromDegrees(src_p.lng, src_p.lat, height)
// }, false)
let ti = setInterval(() => {
h += of
let height = offset * Math.sin(h) + src_p.alt
if (h > pi) h = 0
entity.position = Cesium.Cartesian3.fromDegrees(
src_p.lng,
src_p.lat,
height
)
}, 30)
setTimeout(() => {
clearInterval(ti)
entity.position = Cesium.Cartesian3.fromDegrees(
src_p.lng,
src_p.lat,
src_p.alt
)
}, 3000)
}
}
/**@desc 绘制扇形
* @method sector
* @memberOf Tools*/
calSector(
center = {},
radius = 100,
bearing1 = 25,
bearing2 = 45,
steps = 360,
is84 = false
) {
let c = turf.point([center.lng, center.lat])
let coordinates = turf.sector(c, radius / 1000, bearing1, bearing2, { steps: steps })
.geometry.coordinates
let positions = []
coordinates.forEach((array) => {
array.forEach((item) => {
let pos
if (is84) {
pos = {
lng: item[0],
lat: item[1],
}
}
else {
pos = Cesium.Cartesian3.fromDegrees(item[0], item[1])
}
positions.push(pos)
})
})
return positions
}
/**
* @desc获取紧贴高度
* @param position 坐标
*/
async getClampToHeight(position, objectsToExclude = []) {
if (!this.sdk || !this.sdk.viewer) {
return 0
}
let pos3 = new Cesium.Cartesian3.fromDegrees(position.lng, position.lat);
let position1
try {
position1 = await this.sdk.viewer.scene.clampToHeight(pos3, objectsToExclude) || pos3
} catch (error) {
position1 = pos3
}
let height1 = await this.cartesian3Towgs84(position1, this.sdk.viewer).alt
let height2 = 0
try {
if (this.sdk.viewer.scene.terrainProvider.availability) {
let position2 = await Cesium.sampleTerrainMostDetailed(
this.sdk.viewer.scene.terrainProvider,
[Cesium.Cartographic.fromDegrees(position.lng, position.lat)]
)
position2[0].height && (height2 = position2[0].height)
}
} catch (error) {
height2 = 0
}
if (height1 > height2) {
return Number(height1.toFixed(2))
}
else {
return Number(height2.toFixed(2))
}
}
/**
* @desc 深拷贝对象
* */
deepCopyObj(obj) {
let newobj = null;
//判断是否需要继续进行递归
if (typeof (obj) == 'object' && obj !== null) {
newobj = obj instanceof Array ? [] : {}; //进行下一层递归克隆
for (let i in obj) {
if (i != 'earth' && i != 'Dialog')
newobj[i] = this.deepCopyObj(obj[i])
} //如果不是对象直接赋值
} else newobj = obj;
return newobj;
}
/**
* @desc 度分秒转换
* */
projConvert(status = false, closeCallBack = () => { }) {
if (status) {
projConvertOpen(this.sdk, closeCallBack)
}
else {
projConvertClose()
}
}
/**
* @desc 投影转换
* */
projectionConvert(status = false, closeCallBack = () => { }) {
if (status) {
projectionConvertOpen(this.sdk, closeCallBack)
}
else {
projectionConvertClose()
}
}
/**
* @desc 导出excel
*/
// 导出属性
exportExcel(data) {
let label = '<Row>'
for (let key in data[0]) {
label += `<Cell><Data ss:Type="String">${key}</Data></Cell>`
}
label += '</Row>'
let url = 'data:application/vnd.ms-excel;base64,',
tmplWorkbookXML = '<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?><Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">'
+ '<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>Axel Richter</Author><Created>{created}</Created></DocumentProperties>'
+ '<Styles>'
+ '<Style ss:ID="Currency"><NumberFormat ss:Format="Currency"></NumberFormat></Style>'
+ '<Style ss:ID="Date"><NumberFormat ss:Format="Medium Date"></NumberFormat></Style>'
+ '</Styles>'
+ '{worksheets}</Workbook>'
, tmplWorksheetXML = '<Worksheet ss:Name="{nameWS}"><Table><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="240"/>{rows}</Table></Worksheet>'
, tmplCellXML = '<Cell><Data ss:Type="{nameType}">{data}</Data></Cell>'
, base64 = function (s) {
return window.btoa(unescape(encodeURIComponent(s)))
}
, format = function (s, c) {
return s.replace(/{(\w+)}/g, function (m, p) {
return c[p];
})
}
let ctx = "";
let workbookXML = "";
let worksheetsXML = "";
let rowsXML = "";
let pil = 0;
for (let i = 0; i < data.length; i++) {
if (i == 0) {
rowsXML += label
}
rowsXML += '<Row>';
for (let key in data[i]) {
ctx = {
nameType: 'String',
data: data[i][key]
};
rowsXML += format(tmplCellXML, ctx);
}
rowsXML += '</Row>';
if (i > 0 && (i / 60000) % 1 === 0) {
pil++;
ctx = { rows: rowsXML, nameWS: 'Sheet' + i };
worksheetsXML += format(tmplWorksheetXML, ctx);
rowsXML = "";
rowsXML += label
}
}
ctx = { rows: rowsXML, nameWS: 'Sheet' };
worksheetsXML += format(tmplWorksheetXML, ctx);
rowsXML = "";
ctx = { created: (new Date()).getTime(), worksheets: worksheetsXML };
workbookXML = format(tmplWorkbookXML, ctx);
let link = document.createElement("A");
link.href = url + base64(workbookXML);
link.download = "矢量数据导出.xls"
link.target = '_blank';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
/**
* @desc Gzip解压
*/
decompressGzip(compressedData) {
let decompressedData = pako.inflate(compressedData);
// 将解压缩后的数据转换为字符串
let decompressedString = new TextDecoder().decode(decompressedData);
return decompressedString
}
/**
* @desc cmyk转rbg
* @param {*} color
* @returns
*/
cmykToRgb(color) {
let { c, m, y, k } = color
let rgb = { r: 0, g: 0, b: 0 };
rgb.c = c / 100;
rgb.m = m / 100;
rgb.y = y / 100;
rgb.k = k / 100;
rgb.r = 1 - Math.min(1, rgb.c * (1 - rgb.k) + rgb.k);
rgb.g = 1 - Math.min(1, rgb.m * (1 - rgb.k) + rgb.k);
rgb.b = 1 - Math.min(1, rgb.y * (1 - rgb.k) + rgb.k);
rgb.r = Math.round(rgb.r * 255);
rgb.g = Math.round(rgb.g * 255)
rgb.b = Math.round(rgb.b * 255);
return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;
}
convertPxToRem(sdk, selector) {
const htmlFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);
let list = []
let elementList = []
if (selector) {
list = document.getElementById(sdk.div_id).querySelectorAll(selector)
for (let i = 0; i < list.length; i++) {
elementList.push(list[i], ...list[i].querySelectorAll('*'))
}
}
else {
elementList = document.getElementById(sdk.div_id).querySelectorAll('*');
}
elementList.forEach(element => {
const style = element.style;
const rules = Array.from(style).filter(prop => {
return typeof prop === 'string' && prop.endsWith('px');
});
rules.forEach(prop => {
const pxValue = parseFloat(style[prop]);
const remValue = pxValue / htmlFontSize;
element.style[prop] = `${remValue}rem`;
});
});
}
isConvex(arr = []) {
const { length } = arr
let pre = 0,
curr = 0
for (let i = 0; i < length; ++i) {
let dx1 = arr[(i + 1) % length].lng - arr[i].lng
let dx2 = arr[(i + 2) % length].lng - arr[(i + 1) % length].lng
let dy1 = arr[(i + 1) % length].lat - arr[i].lat
let dy2 = arr[(i + 2) % length].lat - arr[(i + 1) % length].lat
curr = dx1 * dy2 - dx2 * dy1
if (curr != 0) {
if ((curr > 0 && pre < 0) || (curr < 0 && pre > 0)) return false
else pre = curr
}
}
return true
}
getDateTimeString() {
// 创建一个表示当前时间的 Date 对象
const now = new Date();
// 获取年份
const year = now.getFullYear();
// 获取月份(从 0 开始,所以要加 1并将其转换为两位字符串不足两位在前面补零
const month = String(now.getMonth() + 1).padStart(2, '0');
// 获取日期,并将其转换为两位字符串,不足两位在前面补零
const day = String(now.getDate()).padStart(2, '0');
// 获取小时,并将其转换为两位字符串,不足两位在前面补零
const hours = String(now.getHours()).padStart(2, '0');
// 获取分钟,并将其转换为两位字符串,不足两位在前面补零
const minutes = String(now.getMinutes()).padStart(2, '0');
// 获取秒,并将其转换为两位字符串,不足两位在前面补零
const seconds = String(now.getSeconds()).padStart(2, '0');
// 获取毫秒,并将其转换为三位字符串,不足三位在前面补零
const milliseconds = String(now.getMilliseconds()).padStart(3, '0');
// 将年、月、日、时、分、秒、毫秒拼接成所需的字符串
return `${year}${month}${day}${hours}${minutes}${seconds}${milliseconds}`;
}
}
export default Tools