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, // 单位秒});
};