GeoJSON是一种用于编码地理数据结构的格式
{"type": "Feature","geometry": {"type": "Point","coordinates": [125.6, 10.1]},"properties": {"name": "某地点"}
}
一、直接加载GeoJSON文件
// 方式1:通过GeoJsonDataSource加载
viewer.dataSources.add(Cesium.GeoJsonDataSource.load('/path/to/data.geojson', {stroke: Cesium.Color.RED,fill: Cesium.Color.RED.withAlpha(0.5),strokeWidth: 3})
);// 方式2:使用Promise处理
Cesium.GeoJsonDataSource.load('/path/to/data.geojson').then(dataSource => {viewer.dataSources.add(dataSource);viewer.zoomTo(dataSource);}).catch(error => {console.log('Error loading GeoJSON:', error);});
本地直接定义json/GeoJson数据小牛试刀:
<template><div id="cesiumContainer"></div>
</template><script setup>
import * as Cesium from "cesium";
import { onMounted, ref } from "vue";
// import BoxEntityManager from './js/boxEntities.js';
// import { calculateCoordinateOffset } from "./js/coordinateOffset.js";
onMounted(() => {// 使用Cesium的Ion服务进行认证Cesium.Ion.defaultAccessToken ="认证码";// 创建一个Viewer实例const viewer = new Cesium.Viewer("cesiumContainer", {// 使用默认的影像图层和地形图层terrainProvider: Cesium.createWorldTerrain({ requestWaterMask: true }),// 查找位置工具geocoder: false,// 返回首页按钮homeButton: false,// 场景视角sceneModePicker: false,// 图层选择baseLayerPicker: false,// 导航帮助信息navigationHelpButton: false,// 动画播放速度animation: false,// 时间轴timeline: false,// 全屏按钮fullscreenButton: false,// VR按钮vrButton: false,});// 去除logoviewer.cesiumWidget.creditContainer.style.display = "none";// 飞入// WGS84转笛卡尔坐标系var destination = Cesium.Cartesian3.fromDegrees(116.390, 39.890, 1000.0);viewer.camera.flyTo({destination: destination,orientation: {heading: Cesium.Math.toRadians(0.0),pitch: Cesium.Math.toRadians(-10.0),roll: 0.0,},duration: 5, // 飞行持续时间,单位秒});// 1.1 定义GeoJson数据const geojsonData = {//FeatureCollection - 要素集合 ,Feature - 单个要素,GeometryCollection - 几何集合, MultiPolygon - 多面, MultiLineString - 多线,MultiPoint - 多点,Polygon - 面,LineString - 线,Point - 点
//type是其下对象的类型"type": "FeatureCollection","features": [{"type": "Feature",
//properties 包含的各种「变量」和「值」"properties": {"name": "测试点"},
//geometry 是表示几何信息"geometry": {"type": "Point",//地理位置坐标[longitude, latitude, height](高度是可选的)"coordinates": [116.391, 39.917]}}]};// 1.2 加载数据// 创建 GeoJsonDataSource 实例const dataSource = new Cesium.GeoJsonDataSource();// 加载 GeoJSON 数据,并应用样式viewer.dataSources.add(dataSource.load(geojsonData, {strokeWidth: 3,// 边框宽度stroke: Cesium.Color.RED, // 边框颜色fill: Cesium.Color.RED.withAlpha(0.5), // 填充颜色markerSymbol: '📍', // 设置标记符号}));// 自动缩放视图到新添加的数据源viewer.zoomTo(dataSource);
});
二、通过Ajax请求GeoJSON
// 使用fetch请求
fetch('/api/getGeoJson').then(response => response.json()).then(geojsonData => {return Cesium.GeoJsonDataSource.load(geojsonData, {stroke: Cesium.Color.BLUE,fill: Cesium.Color.BLUE.withAlpha(0.5),strokeWidth: 2,markerSymbol: '📍' // 可以使用emoji作为标记});}).then(dataSource => {viewer.dataSources.add(dataSource);viewer.zoomTo(dataSource);});// 使用axios请求
axios.get('/api/getGeoJson').then(response => {return Cesium.GeoJsonDataSource.load(response.data);}).then(dataSource => {viewer.dataSources.add(dataSource);});
三、通过文件输入加载
<!-- HTML部分 -->
<input type="file" id="fileInput" accept=".json,.geojson"><!-- JavaScript部分 -->
<script>
document.getElementById('fileInput').addEventListener('change', function(e) {const file = e.target.files[0];const reader = new FileReader();reader.onload = function(event) {try {const data = JSON.parse(event.target.result);const dataSource = new Cesium.GeoJsonDataSource();viewer.dataSources.add(dataSource.load(data, {stroke: Cesium.Color.BLUE,fill: Cesium.Color.BLUE.withAlpha(0.5)})).then(ds => {viewer.zoomTo(ds);});} catch (error) {console.error('Error parsing JSON:', error);}};reader.readAsText(file);
});
</script>
四、加载本地文件
// 3.1 相对路径加载
Cesium.GeoJsonDataSource.load('./data/local.geojson').then(dataSource => {viewer.dataSources.add(dataSource);viewer.zoomTo(dataSource);});// 3.2 绝对路径加载
Cesium.GeoJsonDataSource.load('http://localhost:8080/data/local.geojson').then(dataSource => {viewer.dataSources.add(dataSource);});
试试:
test.json文件内容
{"type": "FeatureCollection","features": [{"type": "Feature","properties": {"name": "测试点"},"geometry": {"type": "Point","coordinates": [116.391,39.917]}}]
}
<template><div id="cesiumContainer"></div>
</template><script setup>
import * as Cesium from "cesium";
import { onMounted, ref } from "vue";
// import BoxEntityManager from './js/boxEntities.js';
// import { calculateCoordinateOffset } from "./js/coordinateOffset.js";
onMounted(() => {// 使用Cesium的Ion服务进行认证Cesium.Ion.defaultAccessToken ="认证码";// 创建一个Viewer实例const viewer = new Cesium.Viewer("cesiumContainer", {// 使用默认的影像图层和地形图层terrainProvider: Cesium.createWorldTerrain({ requestWaterMask: true }),// 查找位置工具geocoder: false,// 返回首页按钮homeButton: false,// 场景视角sceneModePicker: false,// 图层选择baseLayerPicker: false,// 导航帮助信息navigationHelpButton: false,// 动画播放速度animation: false,// 时间轴timeline: false,// 全屏按钮fullscreenButton: false,// VR按钮vrButton: false,});// 去除logoviewer.cesiumWidget.creditContainer.style.display = "none";// 飞入// WGS84转笛卡尔坐标系var destination = Cesium.Cartesian3.fromDegrees(116.390, 39.890, 1000.0);viewer.camera.flyTo({destination: destination,orientation: {heading: Cesium.Math.toRadians(0.0),pitch: Cesium.Math.toRadians(-10.0),roll: 0.0,},duration: 5, // 飞行持续时间,单位秒});// 1.2 加载本地json数据const dataSource = Cesium.GeoJsonDataSource.load('public/json/test.json').then(dataSource => {viewer.dataSources.add(dataSource);
// 自动缩放视图到新添加的数据源viewer.zoomTo(dataSource);});
});
北京行政区轮廓Geojson加载应用:
下载GeoJson或者json文件练手下载地址存放到public文件夹目录
知识讲解:
笛卡尔坐标系:
var destination = new Cesium.Cartesian3(-2312964.837539202, 4629915.442514007, 4045762.390450758)
中心点计算:
function calculatePolygonCenter (positions) {// 初始化累加器let sumX = 0, sumY = 0, sumZ = 0;const count = positions.length;// 累加所有点的笛卡尔坐标positions.forEach(position => {sumX += position.x;sumY += position.y;sumZ += position.z;});// 计算平均值得到中心点的笛卡尔坐标const centerCartesian = new Cesium.Cartesian3(sumX / count,sumY / count,sumZ / count);// 将笛卡尔坐标转换为经纬度坐标const cartographic = Cesium.Cartographic.fromCartesian(centerCartesian);// 将弧度转换为角度const longitude = Cesium.Math.toDegrees(cartographic.longitude);const latitude = Cesium.Math.toDegrees(cartographic.latitude);const height = cartographic.height;// 使用 fromDegrees 创建最终的笛卡尔坐标const finalCartesian = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);return {cartesian: finalCartesian,degrees: {longitude: longitude,latitude: latitude,height: height}};}
代码:
<template><div id="cesiumContainer"></div>
</template><script setup>
import * as Cesium from "cesium";
import Label from "cesium/Source/Scene/Label";
import { onMounted, ref } from "vue";
onMounted(() => {// 使用Cesium的Ion服务进行认证Cesium.Ion.defaultAccessToken ="认证码";// 创建一个Viewer实例const viewer = new Cesium.Viewer("cesiumContainer", {// 使用默认的影像图层和地形图层terrainProvider: Cesium.createWorldTerrain({ requestWaterMask: true }),// 查找位置工具geocoder: false,// 返回首页按钮homeButton: false,// 场景视角sceneModePicker: false,// 图层选择baseLayerPicker: false,// 导航帮助信息navigationHelpButton: false,// 动画播放速度animation: false,// 时间轴timeline: false,// 全屏按钮fullscreenButton: false,// VR按钮vrButton: false,});// 如果想让所有实体都不受地形影响:// viewer.scene.globe.show = false; // 完全隐藏地球表面// 去除logoviewer.cesiumWidget.creditContainer.style.display = "none";// 1.2 加载数据// 创建 GeoJsonDataSource 实例// 从笛卡尔坐标计算中心点并转换为经纬度// 计算多边形中心点function calculatePolygonCenter (positions) {let sumX = 0, sumY = 0, sumZ = 0;const count = positions.length;positions.forEach(position => {sumX += position.x;sumY += position.y;sumZ += position.z;});const centerCartesian = new Cesium.Cartesian3(sumX / count,sumY / count,sumZ / count);const cartographic = Cesium.Cartographic.fromCartesian(centerCartesian);const longitude = Cesium.Math.toDegrees(cartographic.longitude);const latitude = Cesium.Math.toDegrees(cartographic.latitude);const height = cartographic.height;const finalCartesian = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);return {cartesian: finalCartesian,degrees: {longitude: longitude,latitude: latitude,height: height}};}let box = nullconst dataSource = Cesium.GeoJsonDataSource.load('public/json/beijing.json').then(dataSource => {box = dataSource// 添加数据源到视图viewer.dataSources.add(dataSource);const colorLists = ["DARKMAGENTA","DARKOLIVEGREEN","DARKORANGE","DARKORCHID","ORANGE","YELLOWGREEN","TOMATO","BROWN","CHOCOLATE","DARKGOLDENROD","DARKGRAY","DARKGREEN","DARKKHAKI","DARKRED","DARKSALMON","DARKSEAGREEN","DARKSLATEBLUE","DARKSLATEGRAY",];// 遍历每个实体来设置高度dataSource.entities.values.forEach((entity, index) => {if (entity.polygon) {const height = entity.properties.height ? entity.properties.height : 2000;entity.polygon.extrudedHeight = height; // 设置拉伸高度entity.polygon.material = Cesium.Color[colorLists[index]]; // 设置颜色entity.polygon.outline = false;// 设置边框entity.polygon.closeTop = false; // 是否封闭顶部entity.polygon.closeBottom = true; // 是否封闭底部}if (entity.name && entity.polygon.hierarchy._value.positions) {const center = calculatePolygonCenter(entity.polygon.hierarchy._value.positions);viewer.entities.add({position: Cesium.Cartesian3.fromDegrees(center.degrees.longitude, center.degrees.latitude, center.degrees.height), // 设置标签位置label: {text: entity.name,font: '16px Helvetica',fillColor: Cesium.Color.WHITE,outlineColor: Cesium.Color.BLACK,outlineWidth: 6,verticalOrigin: Cesium.VerticalOrigin.BOTTOM,style: Cesium.LabelStyle.FILL_AND_OUTLINE,pixelOffset: new Cesium.Cartesian2(0, -10),}});}});}).catch(error => {console.error('Error loading GeoJSON:', error);});// 飞入var destination = new Cesium.Cartesian3(-2312964.837539202, 4629915.442514007, 4045762.390450758)viewer.camera.flyTo({destination: destination,orientation: {heading: Cesium.Math.toRadians(0.0),pitch: -0.7871042306871505,roll: 0.0,},duration: 5, // 飞行持续时间,单位秒});viewer.scene.postRender.addEventListener(function (e) {// 相机位置打印,console.log(viewer.camera);})
});</script>