1.获取geojson数据,本地新建一个.ts文件放置数据导出,并引入
获取geojson数据:
DataV.GeoAtlas地理小工具系列
import { scGeojson } from './geojson';
2.加载面
const addPolygonEvt = () => {
viewer.dataSources.add(
Cesium.GeoJsonDataSource.load(scGeojson, {
clampToGround: true, // 贴地
fill: Cesium.Color.AZURE.withAlpha(0.5),
}),
);
};
因为面数据贴地,边界线消失,所以,将面数据转为多线数据,加载一次边界线
3.加载边界线
import { polygonToLine, polygon } from '@turf/turf';
const addPolygonLine = () => {
// 设置一个空数组,用来放置每个面的边界,geojson数据
const lineArr: any[] = [];
scGeojson.features.map((it) => {
if (it.geometry && it.geometry.coordinates) {
it.geometry.coordinates.map((item) => {
let line = polygonToLine(polygon(item)); // 把多面转为多线
lineArr.push(line);
});
}
});
// 1.遍历线数组,可以使用加载实体线方式,把每个面的边界线加载出来
// 2.或则使用加载geojson数据方法,加载出来
lineArr.map((it) => {
// 加载实体方式
// viewer.entities.add({
// polyline: {
// positions: Cesium.Cartesian3.fromDegreesArray(
// flatten(it.geometry.coordinates),
// ),
// material: Cesium.Color.AQUA,
// clampToGround: true,
// },
// });
// 加载geojson方式
viewer.dataSources.add(
Cesium.GeoJsonDataSource.load(it, {
clampToGround: true, // 贴地
stroke: Cesium.Color.AQUA,
strokeWidth: 1,
}),
);
});
};
4.加载点
import { point, FeatureCollection } from '@turf/turf';
const addGeojsonPoint = () => {
const pointGeoJson: FeatureCollection = {
type: 'FeatureCollection',
features: [],
};
scGeojson.features.map((it) => {
pointGeoJson.features.push(point(it.properties.center, it.properties));
});
let data = viewer.dataSources.add(
Cesium.GeoJsonDataSource.load(pointGeoJson, {}),
);
data.then((dataSource: any) => {
const entities = dataSource.entities.values;
for (const item in entities) {
const entity = entities[item];
// if (entity.point) {
entity.billboard = {
image: '/public/images/gg.png',
color: Cesium.Color.AQUA,
width: 40,
height: 40,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, // 贴地
};
entity.label = {
text: entity.name,
font: '14px',
pixelOffset: new Cesium.Cartesian3(0, 30, 0),
fillColor: Cesium.Color.DARKGREEN,
};
}
});
};
效果:
hooks.ts代码:
import * as Cesium from 'cesium';
import { popInfo } from './config';
import { scGeojson } from './geojson';
import { polygonToLine, polygon, point, FeatureCollection } from '@turf/turf';
let viewer: any = {};
export function mountedEvt() {
Cesium.Ion.defaultAccessToken =
'';
viewer = new Cesium.Viewer('cesiumContainer', {
// baseLayerPicker: false,
});
mapFlyEvt(104.065735, 30.659462, 2000000);
addPolygonEvt();
addPolygonLine();
addGeojsonPoint();
}
/**
* @Description 加载geojson点位
* @Author: wms
* @Date: 2023-11-21 15:20:34
*/
const addGeojsonPoint = () => {
const pointGeoJson: FeatureCollection = {
type: 'FeatureCollection',
features: [],
};
scGeojson.features.map((it) => {
pointGeoJson.features.push(point(it.properties.center, it.properties));
});
let data = viewer.dataSources.add(
Cesium.GeoJsonDataSource.load(pointGeoJson, {}),
);
data.then((dataSource: any) => {
const entities = dataSource.entities.values;
for (const item in entities) {
const entity = entities[item];
// if (entity.point) {
entity.billboard = {
image: '/public/images/gg.png',
color: Cesium.Color.AQUA,
width: 40,
height: 40,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, // 贴地
};
entity.label = {
text: entity.name,
font: '14px',
pixelOffset: new Cesium.Cartesian3(0, 30, 0),
fillColor: Cesium.Color.DARKGREEN,
};
}
});
addPopEvt();
};
/**
* @Description 弹窗
* @Author: wms
* @Date: 2023-11-17 11:02:33
*/
export const addPopEvt = () => {
const dom = document.getElementById('popBox');
let popBox: any = new Cesium.InfoBox(dom as string | Element);
viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(
movement: any,
) {
let pickedObject = viewer.scene.pick(movement.position);
if (
Cesium.defined(pickedObject) &&
pickedObject.id instanceof Cesium.Entity
) {
var entity = pickedObject.id;
if (entity.position) {
// 显示弹窗
popBox.container.style.visibility = 'visible';
// 获取位置信息
let entityPosition = entity.position.getValue(
viewer.clock.currentTime,
);
// 传递数据,由于我定义了一个map.js文件,所以没办法把点位数据直接传递给页面,只能用eventBus传递两个文件的数据
popInfo.value = entity.properties;
// 监听 Viewer 的 postRender 事件,在地图移动时更新弹窗位置
viewer.scene.postRender.addEventListener(function () {
try {
if (entityPosition !== null) {
let screenPosition =
Cesium.SceneTransforms.wgs84ToWindowCoordinates(
viewer.scene,
entityPosition,
);
if (screenPosition) {
let leftOffset =
screenPosition.x -
popBox.container.clientWidth / 2;
let topOffset =
screenPosition.y -
popBox.container.clientHeight -
18;
popBox.container.style.left = leftOffset + 'px';
popBox.container.style.top = topOffset + 'px';
}
}
} catch (error) {
console.log(error);
}
});
} else {
popBox.container.style.visibility = 'hidden';
}
} else {
// 隐藏弹窗
popBox.container.style.visibility = 'hidden';
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
};
/**
* @Description 加载面数据
* @Author: wms
* @Date: 2023-11-21 09:36:22
*/
export const addPolygonEvt = () => {
viewer.dataSources.add(
Cesium.GeoJsonDataSource.load(scGeojson, {
clampToGround: true, // 贴地
fill: Cesium.Color.AZURE.withAlpha(0.5),
}),
);
};
/**
* @Description 加载面边界
* @Author: wms
* @Date: 2023-11-21 14:59:04
*/
const addPolygonLine = () => {
// 设置一个空数组,用来放置每个面的边界,geojson数据
const lineArr: any[] = [];
scGeojson.features.map((it) => {
if (it.geometry && it.geometry.coordinates) {
it.geometry.coordinates.map((item) => {
let line = polygonToLine(polygon(item)); // 把多面转为多线
lineArr.push(line);
});
}
});
// 遍历线数组,使用加载实体线方式,把每个面的边界线加载出来
// 或则使用加载geojson数据方法,加载出来
lineArr.map((it) => {
// viewer.entities.add({
// polyline: {
// positions: Cesium.Cartesian3.fromDegreesArray(
// flatten(it.geometry.coordinates),
// ),
// material: Cesium.Color.AQUA,
// clampToGround: true,
// },
// });
viewer.dataSources.add(
Cesium.GeoJsonDataSource.load(it, {
clampToGround: true, // 贴地
stroke: Cesium.Color.AQUA,
strokeWidth: 1,
}),
);
});
};
/**
* @Description 数组扁平化处理
* @Author: wms
* @Date: 2023-11-21 14:50:59
*/
const flatten = (arr: any[]) => {
let result: number[] = [];
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
result = result.concat(flatten(arr[i]));
} else {
result.push(arr[i]);
}
}
return result;
};
/**
* @Description 地图飞行动画
* @Author: wms
* @Date: 2023-11-21 15:11:14
*/
const mapFlyEvt = (lon: number, lat: number, height: number) => {
const position = Cesium.Cartesian3.fromDegrees(lon, lat, height);
// flyTo快速切换视角,带飞行动画,可以设置飞行时长
viewer.camera.flyTo({
destination: position,
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-90),
roll: Cesium.Math.toRadians(0),
},
duration: 3, // 单位秒
});
};