turf.js:panzhiyue.github.io/turfjs-docs…
1. 网站
turf.js 计算 cesium.xin/ 中文网站
iconfont 阿里巴巴 图标库
2. 弧度值与角度值的图片:
3. Cesium.Cartographic.fromCartesian作用
` 方法在 CesiumJS 库中用于将笛卡尔坐标(Cartesian coordinates)转换为地理坐标(Cartographic coordinates)。CesiumJS 是一个用于创建3D地球和2D地图的开源JavaScript库,广泛用于地理信息系统(GIS)、地球物理学、遥感以及游戏开发等领域。
在 CesiumJS 中,笛卡尔坐标系统是基于地心地固(ECEF, Earth-Centered, Earth-Fixed)坐标系的,这种坐标系以地球的中心为原点,使用 X、Y、Z 轴来表示空间中的点。而地理坐标系统则使用经度(longitude)、纬度(latitude)和高度(height)来表示地球上的点,这些值分别表示了点的位置相对于地球赤道和本初子午线的角度,以及点相对于地球椭球体的表面的高度。
Cesium.Cartographic.fromCartesian 方法正是用于执行这种转换的。它接受一个 Cesium.Cartesian3 对象作为参数,这个对象包含了笛卡尔坐标系中的 X、Y、Z 值,然后返回一个 Cesium.Cartographic 对象,该对象包含了对应的经度、纬度和高度值。
// 假设我们有一个 Cesium.Cartesian3 对象,表示地球上的某个点
var cartesian = new Cesium.Cartesian3(1234567.0, 2345678.0, 3456789.0);
// 使用 Cesium.Cartographic.fromCartesian 方法将其转换为地理坐标
var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
// 现在 cartographic 对象包含了经度、纬度和高度
console.log('Longitude:', Cesium.Math.toDegrees(cartographic.longitude)); console.log('Latitude:', Cesium.Math.toDegrees(cartographic.latitude));
console.log('Height:', cartographic.height);
// 注意:CesiumJS 中的经度和纬度是以弧度为单位的,因此如果你需要度为单位,
// 需要使用 Cesium.Math.toDegrees 方法进行转换。
绘制线
addLinkLodLayer(formData) {
formData.forEach((ele) => {
const from = JSON.parse(ele.form)
from.forEach((item) => {
let id = `netLine${item.startId}-${item.endId}`
// item.id = id // 用作树的key,也方便后面通过树控制场景链路显隐。
// item.label = item.netName// 用作树的label
let findExist = netLineEntity.findIndex(el => el.id === id)
if (findExist === -1) {
console.log(' viewer.entities.----', viewer.entities)
let findStart = viewer.entities.values.find(child => child.id === `point${item.startId}`)
let findEnd = viewer.entities.values.find(child => child.id === `point${item.endId}`)
if (findStart && findEnd) {
let positions = [findStart.position._value.clone(), findEnd.position._value.clone()]
let start = DT.Cesium.Cartographic.fromCartesian(positions[0])
let end = DT.Cesium.Cartographic.fromCartesian(positions[1])
let updatePositions = getArc([DT.Cesium.Math.toDegrees(start.longitude), DT.Cesium.Math.toDegrees(start.latitude)], [DT.Cesium.Math.toDegrees(end.longitude), DT.Cesium.Math.toDegrees(end.latitude)], 40, 100000)
// console.log('位置', updatePositions);
const line = new DT.PolylineEntity({
id,
positions: updatePositions.map(function (point) {
return DT.Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2]);
}),
width: 4, // material: DT.Cesium.Color.fromCssColorString('#2e7b69'),
// material: new DT.FlowLineMaterial({
// colorMixMode: false,
// image: this.gradient(),
// repeat: 1,
// speed: -15
// }),
material: new DT.MultipleColorFlowMaterial({
image: process.env.BASE_URL + 'static/img/link.png',
// image: 'data/images/test3.png',
backgroundAlpha: 0.6,
color: ['rgb(255,0,0)', 'rgb(0,255,0)', 'rgb(0,0,255)', 'rgb(255,0,255)', 'rgb(255,255,0)', 'rgb(0,255,255)'],
// color: ['rgb(255,0,0)', 'rgb(0,255,0)'],
repeat: 4,
speed: 20
}),
arcType: DT.Cesium.ArcType.GEODESIC, asynchronous: false
})
netLineEntity.push(line)
console.log(netLineEntity);
lodLayer.add(line)
line.show = false
// line.show = this.netCurrentCheck.includes(item.id)
}
}
})
})
// console.log(netLineEntity);
},
这个转换在处理地球表面的位置时非常有用,尤其是在需要将地球表面的点映射到地图或进行地理空间分析时。
4. 绘制多变形hierarchy
<html lang="en"> <head> <meta charset="UTF-8">
<title>Cesium Polygon Demo</title>
<!-- 引入CesiumJS的CSS -->
<link href="https://cesium.com/downloads/cesiumjs/releases/latest/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<!-- 引入CesiumJS的JS,注意这里使用的是最新版本,你也可以指定具体版本 -->
<script src="https://cesium.com/downloads/cesiumjs/releases/latest/Build/Cesium/Cesium.js"></script>
<style>
html, body, #cesiumContainer { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; }
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script src="app.js">
</script>
</body>
</html>
JavaScript部分 (app.js)
然后,在JavaScript文件中,你需要创建一个Cesium Viewer,并添加一个带有hierarchy属性的多边形实体(Entity)。
// 替换为你的Cesium Ion访问令牌,如果你不使用Cesium Ion服务,则可以省略此行
// Cesium.Ion.defaultAccessToken = '你的Cesium Ion访问令牌';
// 初始化Cesium Viewer var viewer = new Cesium.Viewer('cesiumContainer', { terrainProvider: Cesium.createWorldTerrain()
// 可选,加载地形数据 });
// 定义一个多边形的顶点坐标(经纬度),注意这里的坐标需要是闭合的,即首尾坐标相同
var polygonHierarchy = Cesium.PolygonHierarchy.fromCartesianArray([ Cesium.Cartesian3.fromDegrees(-115.0, 37.0), Cesium.Cartesian3.fromDegrees(-107.0, 37.0), Cesium.Cartesian3.fromDegrees(-107.0, 33.0), Cesium.Cartesian3.fromDegrees(-115.0, 33.0),
// 注意:这里为了闭合多边形,我们再次添加了第一个点 Cesium.Cartesian3.fromDegrees(-115.0, 37.0) ]); // 创建一个多边形实体并添加到viewer中 viewer.entities.add({ polygon: { hierarchy: polygonHierarchy,
// 配置多边形的填充色和边框 material: Cesium.Color.fromCssColorString('#4CAF50'), // 填充色,这里使用CSS颜色字符串
outline: true, // 显示边框 outlineColor: Cesium.Color.WHITE, // 边框颜色
outlineWidth: 2 // 边框宽度 } }); // (可选)将视角飞到多边形所在位置
// viewer.zoomTo(viewer.entities); // 注意:zoomTo方法可能需要根据实际情况调整,这里只是一个示例
for (let key in params) {
const item = params[key]
const response = await fetch(item.areaData)
const { features } = await response.json();
const data = features[0].geometry.coordinates
let newArray = []
const polylineInstance = []
for (let i = 0; i < data.length; i++) {
newArray.push(data[i][0], data[i][1])
if (i % 2 === 0) {
const endPosition = DT.Cesium.Cartesian3.fromDegrees(data[i][0], data[i][1], 0)
polylineInstance.push(createPolyLine(item.position, endPosition))
}
}
//添加多边形
let polygon = viewer.entities.add({
name: 'polygon',
polygon: {
//显示
show: true,
//层级结构,轮廓线坐标
hierarchy: {
positions: DT.Cesium.Cartesian3.fromDegreesArray(newArray),
},
height: 1000,
heightReference: DT.Cesium.HeightReference.NONE,
extrudedHeightReference: DT.Cesium.HeightReference.NONE,
stRotation: Math.PI,
granularity: Math.PI / 180,
fill: true,
//材质
material: DT.Cesium.Color.GREEN.withAlpha(0.4),
//是否开启轮廓线
outline: true,
//轮廓线颜色
outlineColor: DT.Cesium.Color.AQUA,
//轮廓线宽度
outlineWidth: 1,
//先前坐标高度 -只根据经纬度创建几个高度,不随地球曲率生成曲面
perPositionHeight: false,
//顶部封口
closeTop: true,
//底部封口
closeBottom: true,
//两点之间连线方式:NONE 直接连接 GEODESIC 测地线, RHUMB 恒向线
arcType: DT.Cesium.ArcType.GEODESIC,
//阴影类型
shadows: DT.Cesium.ShadowMode.ENABLED,
}
})
//添加线
let primitives = viewer.primitives;
let primitiveCollection = new DT.Cesium.PrimitiveCollection();
primitives.add(primitiveCollection);
//创建模型
let model = await createModel(item.modelUrl, item.position, item.scale, primitiveCollection);
let currentPolyline;
const randomIndexes = [1, 4, 5, 9, 10, 15, 17, 22, 23, 27, 29, 35, 36, 37, 45, 47, 55, 57, 65, 66, 70, 72, 85, 95, 97, 100, 102, 111, 123, 135, 140, 141, 150, 152, 160]
viewer.cesiumViewer.scene.preRender.addEventListener(async function () {
const frontPosition = getCameraFrontPosition(item.distanceFromCamera, item.verticalOffset, item.horizontalOffset);
//创建模型位置矩阵
//更新模型矩阵
model.modelMatrix = DT.Cesium.Transforms.eastNorthUpToFixedFrame(frontPosition);
//每帧都会计算位置和连线
// const newArray = []
const polylineInstance = []
for (let i = 0; i < randomIndexes.length; i++) {
const value = randomIndexes[i]
if (data[value]) {
const endPosition = DT.Cesium.Cartesian3.fromDegrees(data[value][0], data[value][1], 0)
polylineInstance.push(createPolyLine(frontPosition, endPosition))
}
}
if (currentPolyline) {
removePolyline(currentPolyline, primitiveCollection);
}
currentPolyline = addPolyline(polylineInstance, primitiveCollection);
});
}
注意
- Cesium Ion访问令牌:如果你不使用Cesium Ion服务(如地形数据、影像数据等),则可以省略
Cesium.Ion.defaultAccessToken的设置。 - 多边形闭合:在定义
polygonHierarchy时,坐标数组需要是闭合的,即首尾坐标需要相同,以确保多边形是封闭的。 - zoomTo方法:Cesium的
zoomTo方法可能并不总是直接接受viewer.entities作为参数。如果需要自动将视角调整到特定实体或一组实体上,你可能需要使用其他方法,如viewer.flyTo结合实体的位置来计算飞行目标。
以上Demo展示了如何在Cesium中创建一个简单的多边形实体,并通过hierarchy属性定义了其顶点坐标。你可以根据需要调整多边形的颜色、边框等属性。