Cesium API
demo 仓库地址
token
注册一个 Cesium Ion
,在 Access Tokens
的右侧的 Token
处,复制到 js
文件中,赋值到 token
,并设置:
Cesium.Ion.defaultAccessToken = token;
Cesium
使用 Cesium.Viewer()
创建一个 Cesium
,第一个参数是创建的 Cesium
容器( DOM
)的 id
名,不需要加 #
,第二个参数是配置项,用参数配置。
const viewer = new Cesium.Viewer('', {
geocoder: false, // 是否创建右上角的查询按钮(右上第一个)
homeButton: false, // 是否创建 home 按钮(右上第二个)
sceneModePicker: false, // 是否创建右上角的切换地图的按钮(右上第三个)
baseLayerPicker: false, // 是否创建右上角 BaseLayerPicker 小部件(右上第四个)
navigationHelpButton: false, // 是否创建右上角的导航帮助按钮(右上第五个
// vrButton: true, // 是否创建右下角的 VR 按钮,默认值为 true
animation: false, // 是否创建左下角的动画小部件
fullscreenButton: false, // 是否创建右下角全屏按钮
timeline: false, // 是否创建最下方的时间线
infoBox: false, // 点击实体是否展示详情
selectionIndicator: false, // 点击实体是否显示选中样式
// 左下方的 Cesium logo 使用 css 删除
terrainProvider: Cesium.createWorldTerrain(), // 加载地球椭球体
});
更多配置
entities.add()
// 点实体
viewer.entities.add({
position: position, // 格式为世界坐标的点位置
point: {
show: ture, // 点是否可见
pixelSize: Number, // 点的大小
color: color, // 点的颜色
outlineClor: color, // 边框颜色
outlineWidth: Number, // 轮廓宽度
},
});
// 线实体
viewer.entities.add({
polyline: {
show: Boolean, // 线是否可见
positions: positions, // 格式为世界坐标的线位置数组
width: Number, // 线的宽度
material: color, // 线的颜色
clampToGround: Boolean, // 线是否固定在地面
},
});
// 面实体
viewer.entities.add({
polygon: {
show: Boolean, // 面是否可见
hierarchy: positions, // 格式为世界坐标的面位置数组
height: Number, // 面相对于椭球表面的高度
fill: Boolean, // 面是否有填充
material: color, // 面的填充颜色
outline: Boolean, // 面是否有边框
outlinColor: color, // 边框的颜色
outlineWidth: Number, // 边框的宽度,无论设置为多少宽度始终只会显示为 1
perPositionHeight: Boolean, // 面是否使用每个位置的高度
},
});
Cesium.TypeGraphices()
// 点实体
viewer.entities.add({
position: position, // 格式为世界坐标的点位置
point: new Cesium.PointGraphics({
show: Boolean, // 点是否可见
pixelSize: Number, // 点的大小
color: color, // 点的颜色
outlineClor: color, // 边框宽度
outlineWidth: Boolean, // 轮廓颜色
});
});
// 线实体
viewer.entities.add({
golyline: new Cesium.PolylineGraphics({
show: Boolean, // 线是否可见
positions: positions, // 格式为 Cartesian3 的线位置数组
width: Number, // 线的宽度
material: color, // 线的颜色
clampToGround: Boolean, // 线是否固定在地面
});
});
// 面实体
viewer.entities.add({
golygon: new Cesium.PolygonGraphics({
show: Boolean, // 面是否可见
hierarchy: positions, // 格式为 Cartesian3 的面位置数组
height: Number, // 面相对于椭球表面的高度
fill: Boolean, // 面是否有填充
material: color, // 面的填充颜色
outline: Boolean, // 面是否有边框
outlinColor: color, // 边框的颜色
outlineWidth: Number, // 边框的宽度,无论设置为多少宽度始终只会显示为 1
perPositionHeight: Boolean, // 面是否使用每个位置的高度
});
});
Cesium中的坐标相互转换
平面坐标系( Cartesian2
)
new Cesium.Cartesian2(x, y)
笛卡尔空间直角坐标系-世界坐标( Cartesian3
)
new Cesium.Cartesian3(x, y, z);
弧度
new Cesium.Cartographic(lng, lat, height);
经纬度
(lng, lat)
// 经纬度转为世界坐标
Cesium.Cartesian3.fromDregrees(lng, lat, height);
// 世界坐标转为经纬度
const ellipsoid = viewer.scene.globe.ellipsoid;
const cartiesian3 = new Cesium.Cartesian3(x, y, z);
const cartographic = ellipsoid.cartesianToCartographic(cartesian3);
const lng = Cesium.Math.toDegrees(cartographic.longitude);
const lat = Cesium.Math.toDegrees(cartographic.latitude);
const height = cartographic.height;
封装为方法
// 世界坐标转为经纬度
// 参数可以是一个世界坐标,也可以是一组世界坐标数组
function toLatAndLng(position) {
if (Array.isArray(position)) {
return position.map(item => toLatAndLng(item));
} else {
const cartographic = ellipsoid.cartesianToCartographic(position);
const lng = Cesium.Math.toDegrees(cartographic.longitude);
const lat = Cesium.Math.toDegrees(cartographic.latitude);
const height = cartographic.height;
return [lng, lat, height];
}
};
// 屏幕坐标转为世界坐标
const pick1 = new Cesium.Cartesian2(0, 0);
const cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(pick1), viewer.scene);
// 世界坐标转为屏幕坐标
Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, Cartesian3)
// 弧度转为经纬度
Cesium.Math.toRadians(degrees);
// 经纬度转为弧度
Cesium.Math.toDregees(radians);
// 返回指定经度和纬度的二维区域
new Cesium.Rectangle.fromDegrees(
Number, // 最西的经度
Number, // 最南端的纬度
Number, // 最东的经度
Number // 最北端的纬度
);
// 返回颜色
Cesium.Color.fromCssColorString(
color // css 的颜色样式
).withAlpha(
Number // 颜色的透明度,0 - 1
);
封装为方法
// 跳转的到一个区域,且最后得到的图形是整个范围的 1/3
function flyToRectangle(position, time) {
const WE = position.east - position.west;
const NS = position.north - position.south;
viewer.camera.flyTo({
destination: Cesium.Rectangle.fromDegrees(
position.west - WE,
position.south - NS,
position.east + WE,
position.north + NS
),
duration: time || 0.8,
});
};
// 切换为三维
viewer.scene.morphTo3D({
duration: Number // 切换花费的时间
});
// 切换为二维
viewer.scene.morphTo2D({
duration: Number // 切换花费的时间
});
flyTo()
// 跳转设置点或区域
viewer.camera.flyTo({
// destination: position, 跳转到某一点时,格式为 Cartesian3 的位置
destination: Rectangle, // 跳转到某一区域
duration: Number, // 镜头飞行时长
});
// 跳转某一实体
viewer.flyTo(
target, // 实体
{
duration: Number, // 镜头飞行时长
maximumHeight: Number, // 镜头飞行的最大高度
offset: new Cesium.HeadingPitchRangce(
Number, // 航向角,格式为弧度
Number, // 俯仰角,格式为弧度
Number, // 据中心的距离
),
},
);
zoomTo()
// 跳转某一实体,且可以设置航向角,俯仰角和据中心距离
viewer.zommTo(
target, // 实体
new Cesium.HeadingPitchRange(
Number, // 航向角,格式为弧度
Number, // 俯仰角,格式为弧度
Number, // 据中心的距离
),
);
GeoJsonDataSource
// 导入格式为 GeoJSON 或 TopoJSON 的实体
viewer.dataSources.add(Cesium.GeoJsonDataSource.load(data, { // data 为需要加载的数据
markerSize: Number, // 为每个点创建的地图图钉的默认大小
stroke: Color, // 折线和多边形轮廓的默认颜色
strokeWidth: Number, // 折线和多边形轮廓的默认宽度
fill: Color, // 多边形内部的默认颜色
clampToGround: Boolean, // 是否固定在地面
})).then(dataSourcre => {
console.log(dataSourcre);
});
KmlDataSource
// 导入格式为 KML 的实体
viewer.dataSources.add(data, { // data 为需要加载的数据
camera: camera, // 用于viewRefreshModes并将摄像机属性发送到网络链接的摄像机
canvas: canvas, // 用于将查看器属性发送到网络链接的画布
clampToGround: Boolean, // 是否固定在地面
}).then(dataSource => {
console.log(dataSource);
});
事件解析
鼠标左键
事件类型 | 含义 |
---|---|
LEFT_CLICK | 单击 |
LEFT_DOUBLE_CLICK | 双击 |
LEFT_DOWN | 左键按下 |
LEFT_UP | 左键弹起 |
鼠标中键
事件类型 | 含义 |
---|---|
MIDDLE_CLICK | 点击 |
MIDDLE_DOWN | 中键按下 |
MIDDLE_UP | 中键弹起 |
鼠标右键
事件类型 | 含义 |
---|---|
RIGHT_CLICK | 点击 |
RIGHT_DOWN | 右键按下 |
RIGHT_UP | 右键弹起 |
其他鼠标事件
事件类型 | 含义 |
---|---|
MOUSE_MOVE | 鼠标移动事件 |
WHEEL | 鼠标滚轮事件 |
Cesium.ScreenSpaceEventHandler()
使用 Cesium.ScreenSpaceEventHandler()
获取需要注册点击事件的 Cesium
const handler = new Cesium.ScreenSpaceEventHandler(viewer);
Cesium.ScreenSpaceEventType()
使用 Cesium.ScreenSpaceEventType()
获取触发事件的条件,例如获取点击左键
const LEFT_CLICK = Cesium.ScreenSpaceEventType(LEFT_CLICK);
handler.setInputAction()
使用 handler.setInputAction()
监听触发的事件,第一个参数是触发事件调用的方法函数,第二个参数是触发事件的类型
handler.setInputAction(event => {
console.log(event);
}, LEFT_CLICK);
event
中的位置格式是平面坐标
viewer.scene.dirllPick()
// 返回包含点的所有实体集合,是一个数组
viewer.scene.dirllPick(
position, // 平面坐标
Number // 收集到指定个数的实体就停止获取,可选
);
配合点击事件
const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
handler.setInputAction(event => {
const entities = viewer.scene.dirllPick(event.position);
console.log(entities);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
viewer.selectedEntityChanged.addEventListener
// 点击左键时,若点击的实体产生变化才会调用
viewer.selectedEntityChanged.addEventListener(entity => {
console.log(entity);
})
在鼠标移动事件中,第一次触发移动事件时,就创建一个点实体,以后触发移动事件时就先删除上一次触发移动事件创建的实体,再创建一个新的实体。
动态绘制线与动态绘制点相似,但是,在绘制过程中, polyline
中的 positions
属性值需要使用 Cesium.CallbackProperty()
方法来获取。
viewer.entities.add({
polyline: {
positions: new Cesium.CallbackProperty(function() {
return positions;
}, false),
material: Color,
width: Number,
}
});
动态绘制面 demo
动态绘制面与动态绘制线相似,但是,在 polygon
中的 hierarchy
属性值除需要使用 Cesium.CallbackProperty()
方法来获取外,还需要使用 Cesium.PolygonHierarchy()
返回。
viewer.entities.add({
polygon: {
hierarchy: new Cesium.CallbackProoerty(function() {
return new Cesium.PolyHierarchy(positions);
}, false),
material: Color,
}
});
使用方法 Cesium.UrlTemplateImageryProvider()
引入地图资源
// Cesium 加载高德矢量地图
var layer = new Cesium.UrlTemplateImageryProvider({
url: "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}",
minimumLevel: 4,
maximumLevel: 18
});
// Cesium 加载高德影像
var imgLayer = new Cesium.UrlTemplateImageryProvider({
url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
minimumLevel: 3,
maximumLevel: 18
});
// Cesium 加载注记要素
var annLayer = new Cesium.UrlTemplateImageryProvider({
url: "http://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8",
minimumLevel: 3,
maximumLevel: 18
});
// Cesium 加载天地图
var dmap = new Cesium.UrlTemplateImageryProvider({
url: "https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
minimumLevel: 4,
maximumLevel: 18
});
viewer.imageryLayers.addImageryProvider();
高德地图 API
@turf/turf
使用插件 turf
,CDN
引入
<script src="https://cdn.jsdelivr.net/npm/@turf/turf@5/turf.min.js">script>
import
引入
import turf as * from "@turf/turf";
// positions 需要计算线状实体的位置信息,是一个数组,每个元素是经纬度
const polyline = turf.lineString(positions);
const length = turf.length(polyline);
// hierarchy 需要计算面状实体的位置信息,是一个数组,每个元素是经纬度,且第一个元素与最后一个元素要相同
const polygon = turf.polygon([hirerachy]);
const area = turf.area(polygon);
// 开启抗锯齿
viewer.scene.postProcessStages.fxaa.enabled = true;
// 取消默认的左键双击事件
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);