1. 概述

将路线加载到三维地图中,能直观显示道路的坡度变化,协同DEM和遥感影像,能极大丰富道路的可视化效果

本文此处基于Cesium,加载地形数据,叠加遥感影像,再叠加路网数据,形成三维地图,效果如下:

2. 代码实现

2.1 CDN引入

笔者这里使用 CDN 引入 Cesium,另外后续加载路网数据需要使用Ajax,这里引入jQuery

<!-- Include the CesiumJS JavaScript and CSS files -->
<script src="https://cesium.com/downloads/cesiumjs/releases/1.92/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.92/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>

2.2 加载地形

笔者这里使用Cesium的地形数据

// Initialize the Cesium Viewer in the HTML element with the `cesiumContainer` ID.
var viewer = new Cesium.Viewer('cesiumContainer', {
terrainProvider: Cesium.createWorldTerrain()
});

2.3 加载遥感影像

笔者这里使用Bing的遥感影像

var bingStyle = [
Cesium.BingMapsStyle.AERIAL_WITH_LABELS,
Cesium.BingMapsStyle.COLLINS_BART,
Cesium.BingMapsStyle.CANVAS_GRAY,
Cesium.BingMapsStyle.CANVAS_LIGHT,
Cesium.BingMapsStyle.CANVAS_DARK,
Cesium.BingMapsStyle.ORDNANCE_SURVEY,
Cesium.BingMapsStyle.ROAD,
Cesium.BingMapsStyle.AERIAL,
];
var bingMapProvider = new Cesium.BingMapsImageryProvider({
url: "https://dev.virtualearth.net",
key: "AmXdbd8UeUJtaRSn7yVwyXgQlBBUqliLbHpgn2c76DfuHwAXfRrgS5qwfHU6Rhm8",
mapStyle: bingStyle[7],
});
viewer.imageryLayers.addImageryProvider(bingMapProvider);

2.4 设置视点

笔者这里将视点即观察点设置为长沙岳麓山附近

// Fly the camera to Changsha at the given longitude, latitude, and height.
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(112.9448, 28.1708, 1200),
orientation: {
heading: Cesium.Math.toRadians(0.0),
pitch: Cesium.Math.toRadians(-15.0),
}
});

2.5 小结测试

到目前为止,整体代码如下:

<!DOCTYPE html>
<html lang="zh-cn"> <head>
<meta charset="utf-8">
<!-- Include the CesiumJS JavaScript and CSS files -->
<script src="https://cesium.com/downloads/cesiumjs/releases/1.92/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.92/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head> <body>
<div id="cesiumContainer"></div>
<script>
// Your access token can be found at: https://cesium.com/ion/tokens.
// Replace `your_access_token` with your Cesium ion access token. // Cesium.Ion.defaultAccessToken = 'your_access_token'; // Initialize the Cesium Viewer in the HTML element with the `cesiumContainer` ID.
var viewer = new Cesium.Viewer('cesiumContainer', {
terrainProvider: Cesium.createWorldTerrain()
}); var bingStyle = [
Cesium.BingMapsStyle.AERIAL_WITH_LABELS,
Cesium.BingMapsStyle.COLLINS_BART,
Cesium.BingMapsStyle.CANVAS_GRAY,
Cesium.BingMapsStyle.CANVAS_LIGHT,
Cesium.BingMapsStyle.CANVAS_DARK,
Cesium.BingMapsStyle.ORDNANCE_SURVEY,
Cesium.BingMapsStyle.ROAD,
Cesium.BingMapsStyle.AERIAL,
];
var bingMapProvider = new Cesium.BingMapsImageryProvider({
url: "https://dev.virtualearth.net",
key: "AmXdbd8UeUJtaRSn7yVwyXgQlBBUqliLbHpgn2c76DfuHwAXfRrgS5qwfHU6Rhm8",
mapStyle: bingStyle[7],
});
viewer.imageryLayers.addImageryProvider(bingMapProvider); // Fly the camera to Changsha at the given longitude, latitude, and height.
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(112.9448, 28.1708, 1200),
orientation: {
heading: Cesium.Math.toRadians(0.0),
pitch: Cesium.Math.toRadians(-15.0),
}
}); </script>
</div>
</body> </html>

我们测试其效果,笔者这里使用的是VS Code的Live Server插件打开:

2.6 路网加载

路网(Ployline)的加载方式主要有两种:

  • 使用Viewer.entities
  • 使用Cesium.GroundPolylinePrimitive

此处笔者的示例数据如下:

112.91725386767241,28.18088394284931,47.28909519744873
112.91765398304703,28.18080062181755,52.27461015478515
112.94271541045252,28.18907071666184,34.729803589843755
112.94263996370492,28.18929672498712,44.796474171875005
112.94263996370492,28.18929672498712,44.796474171875005
112.94271541045252,28.18907071666184,34.729803589843755
112.94264628370074,28.190083096717974,36.39323925
112.94259227750655,28.18977721403619,24.70917075
112.94259227750655,28.18977721403619,24.70917075
112.94264628370074,28.190083096717974,36.39323925
112.94264628370074,28.190083096717974,36.39323925
112.94255004568583,28.19039785102342,46.969459281249996
112.94255004568583,28.19039785102342,46.969459281249996
112.94264628370074,28.190083096717974,36.39323925
112.94263996370492,28.18929672498712,44.796474171875005
112.942639007202,28.18939392688125,41.37971635546875
112.942639007202,28.18939392688125,41.37971635546875
112.94263996370492,28.18929672498712,44.796474171875005
112.942639007202,28.18939392688125,41.37971635546875
112.94259227750655,28.18977721403619,24.70917075
112.94259227750655,28.18977721403619,24.70917075
112.942639007202,28.18939392688125,41.37971635546875
112.94255707716033,28.19747999678687,78.00138119911344
112.94251096347146,28.197641540468794,62.308529711560176
112.94251096347146,28.197641540468794,62.308529711560176
112.94251086130572,28.19765191789022,62.308529711560176
112.94251086130572,28.19765191789022,62.308529711560176
112.94216077246415,28.19774676732831,88.14892901957208
112.94251096347146,28.197641540468794,62.308529711560176
112.94255707716033,28.19747999678687,78.00138119911344
112.94251086130572,28.19765191789022,62.308529711560176
112.94251096347146,28.197641540468794,62.308529711560176

数据文件的名字为trans_final_map_with_dem.csv,笔者使用Ajax加载并解析

前者Viewer.entities的代码如下:

$.ajax({
url: 'trans_final_map_with_dem.csv',
dataType: 'text',
}).done(successFunction); var groundPolylineGeometryInstances = [];
function successFunction(data) {
var allRows = data.split(/\r?\n|\r/);
for (let i = 0; i < allRows.length - 1; i = i + 2) {
var rowCell1 = allRows[i].split(',');
var rowCell2 = allRows[i + 1].split(','); viewer.entities.add({
polyline: {
positions: Cesium.Cartesian3.fromDegreesArrayHeights([
rowCell1[0], rowCell1[1],rowCell1[2],
rowCell2[0], rowCell2[1],rowCell2[2]
]),
width: 4.0,
material: Cesium.Color.ORANGE,
clampToGround: true
}
})
}
}

后者Cesium.GroundPolylinePrimitive的代码如下:

$.ajax({
url: 'trans_final_map_with_dem.csv',
dataType: 'text',
}).done(successFunction); var groundPolylineGeometryInstances = [];
function successFunction(data) {
var allRows = data.split(/\r?\n|\r/);
for (let i = 0; i < allRows.length - 1; i = i + 2) {
var rowCell1 = allRows[i].split(',');
var rowCell2 = allRows[i + 1].split(','); groundPolylineGeometryInstances.push(new Cesium.GeometryInstance({
geometry: new Cesium.GroundPolylineGeometry({
positions: Cesium.Cartesian3.fromDegreesArrayHeights([
rowCell1[0], rowCell1[1], rowCell1[2],
rowCell2[0], rowCell2[1], rowCell2[2]
]),
width: 4.0,
}),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.ORANGE.withAlpha(1.0))
}
}));
}
var groundPolylinePrimitive = new Cesium.GroundPolylinePrimitive({
geometryInstances: groundPolylineGeometryInstances,
show: true,
appearance: new Cesium.PolylineColorAppearance()
});
viewer.scene.groundPrimitives.add(groundPolylinePrimitive)
}

注意:

  • 笔者这里的数据是每两个点构成一个Polyline,每一行最后是换行符'\n'
  • 数据量大时尽可能使用Cesium.GroundPolylinePrimitive

2.7 最终测试

整体代码如下:

<!DOCTYPE html>
<html lang="zh-cn"> <head>
<meta charset="utf-8">
<!-- Include the CesiumJS JavaScript and CSS files -->
<script src="https://cesium.com/downloads/cesiumjs/releases/1.92/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.92/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head> <body>
<div id="cesiumContainer"></div>
<script>
// Your access token can be found at: https://cesium.com/ion/tokens.
// Replace `your_access_token` with your Cesium ion access token. // Cesium.Ion.defaultAccessToken = 'your_access_token'; // Initialize the Cesium Viewer in the HTML element with the `cesiumContainer` ID.
var viewer = new Cesium.Viewer('cesiumContainer', {
terrainProvider: Cesium.createWorldTerrain()
}); var bingStyle = [
Cesium.BingMapsStyle.AERIAL_WITH_LABELS,
Cesium.BingMapsStyle.COLLINS_BART,
Cesium.BingMapsStyle.CANVAS_GRAY,
Cesium.BingMapsStyle.CANVAS_LIGHT,
Cesium.BingMapsStyle.CANVAS_DARK,
Cesium.BingMapsStyle.ORDNANCE_SURVEY,
Cesium.BingMapsStyle.ROAD,
Cesium.BingMapsStyle.AERIAL,
];
var bingMapProvider = new Cesium.BingMapsImageryProvider({
url: "https://dev.virtualearth.net",
key: "AmXdbd8UeUJtaRSn7yVwyXgQlBBUqliLbHpgn2c76DfuHwAXfRrgS5qwfHU6Rhm8",
mapStyle: bingStyle[7],
});
viewer.imageryLayers.addImageryProvider(bingMapProvider); $.ajax({
url: 'trans_final_map_with_dem.csv',
dataType: 'text',
}).done(successFunction); // const polylines = new Cesium.PolylineCollection();
var groundPolylineGeometryInstances = [];
function successFunction(data) {
var allRows = data.split(/\r?\n|\r/);
for (let i = 0; i < allRows.length - 1; i = i + 2) {
var rowCell1 = allRows[i].split(',');
var rowCell2 = allRows[i + 1].split(','); // viewer.entities.add({
// polyline: {
// positions: Cesium.Cartesian3.fromDegreesArrayHeights([
// rowCell1[0], rowCell1[1],rowCell1[2],
// rowCell2[0], rowCell2[1],rowCell2[2]
// ]),
// width: 4.0,
// material: Cesium.Color.ORANGE,
// clampToGround: true
// }
// })
// }
groundPolylineGeometryInstances.push(new Cesium.GeometryInstance({
geometry: new Cesium.GroundPolylineGeometry({
positions: Cesium.Cartesian3.fromDegreesArrayHeights([
rowCell1[0], rowCell1[1], rowCell1[2],
rowCell2[0], rowCell2[1], rowCell2[2]
]),
width: 4.0,
}),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.ORANGE.withAlpha(1.0))
}
}));
// }
}
var groundPolylinePrimitive = new Cesium.GroundPolylinePrimitive({
geometryInstances: groundPolylineGeometryInstances,
show: true,
appearance: new Cesium.PolylineColorAppearance()
});
viewer.scene.groundPrimitives.add(groundPolylinePrimitive)
} // Fly the camera to Changsha at the given longitude, latitude, and height.
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(112.9448, 28.1708, 1200),
orientation: {
heading: Cesium.Math.toRadians(0.0),
pitch: Cesium.Math.toRadians(-15.0),
}
}); </script>
</div>
</body> </html>

最后效果如下:

参考资料

[1]Sandcastle

[2]Polylines on Terrain

[3]cesiumjs/ref-doc/Viewer

[4]遥感影像和DEM数据获取处理、GeoServer切片发布并使用Cesium加载

Cesium加载三维路线的更多相关文章

  1. Cesium加载三维倾斜摄影数据

    具体技术来源自论文 基于Cesium的倾斜摄影三维模型Web加载与应用研究. 技术架构图 应用实例 利用一个实际实例来详细说明如何利用Cesium加载倾斜摄影数据,并进行可视化和交互操作. 首先,利用 ...

  2. cesium加载倾斜摄影,添加billboard并注册点击事件

    完整示例代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  3. arcgis api for JavaScript _加载三维图层(scene layer)

    arcgis api for JavaScript _加载三维图层(scene layer) arcgis api for JavaScript  4.x 版本增加对三维的支持. 关于三维图层(sce ...

  4. cesium加载gltf模型

    cesium加载gltf模型 一.采用vue-cesium:在项目里加载依赖包.命令如下: npm i --save vue-cesium 在main.js中加入如下代码: https://www.n ...

  5. Cesium加载地形数据只显示半个地球

    Cesium第0级地形包括两个瓦片:0/0/0.terrain,0/1/0.terrain,分别为左半球和右半球(具体参考:https://blog.csdn.net/u013929284/artic ...

  6. cesium加载gltf模型点击以及列表点击定位弹窗

    前言 cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材. 之 ...

  7. geotrellis使用(三十五)Cesium加载geotrellis TMS瓦片

    前言 做任何事情都不是想象中的那么简单.好久没有更新技术博客了,跟最近瞎忙有很大关系,虽说是瞎忙也抽空研究了些技术. 主要是前端渲染,像原生的WebGL和Cesium.WebGL写了几篇博客,自我感觉 ...

  8. cesium 加载倾斜摄影模型(这里有一坑)

    代码如下: // Construct the default list of terrain sources. var terrainModels = Cesium.createDefaultTerr ...

  9. cesium 加载TMS影像(已经切片)

    TMS影像数据格式 加载影像的代码: var layers = viewer.scene.imageryLayers; var blackMarble = layers.addImageryProvi ...

  10. cesium 加载shp格式的白模建筑

    ceisum加载shp格式的建筑.有两种思路,目前推荐第二种. 方法一:将shp格式转换为geojson格式,然后采用cesium提供的接口加载到ceisum中. 严重缺陷:在面对大场景问题,即数据量 ...

随机推荐

  1. 【算法总结】【队列均LinkedList】栈和队列、双端队列的使用及案例

    1.栈 初始化:Stack<E> stack = new Stack<>(); 出栈:stack.pop() 或 stack.remove(stack.size() - 1) ...

  2. (java 实现开箱即用基于 redis 的分布式锁

    项目简介 lock 为 java 设计的分布式锁,开箱即用,纵享丝滑. 开源地址:https://github.com/houbb/lock 目的 开箱即用,支持注解式和过程式调用 基于 redis ...

  3. Django框架:2、静态文件配置、form表单、request对象、pycharm链接数据库、django链接数据库、ORM框架

    Django框架 目录 Django框架 一.静态文件配置 1.静态文件 2.配置方法 二.form表单 1.action属性 2.method属性 三.request对象 1.基本用法 四.pych ...

  4. python模块的含义

    目录 模块简介 模块的本质 python模块的历史 python模块的表现形式 模块的分类 导入模块的两种句式 强调 import句式 import流程推导 练习 from...import...句式 ...

  5. jQuery基本使用

    目录 一:jQuery查找标签 1.基本选择器 二:分组与嵌套 三:组合选择器 四:jQuery基本筛选器 五:属性选择器 1.属性标签 六:JQuery表单筛选器 1.type属性 2.表单对象属性 ...

  6. python循环结构之for循环

    在python中,for循环是应用非常广的循环语句,遍历字典.遍历列表等等... # for语句结构 for 遍历 in 序列: 执行语句 遍历字典 lipsticks = {"Chanel ...

  7. pymysql.err.ProgrammingError: (1146, "Table 'autoplatform.webcasestepinfo' doesn't exist"

    在使用jmeter调试接口时,提示pymysql.err.ProgrammingError: (1146, "Table 'autoplatform.webcasestepinfo' doe ...

  8. Redis RDB 与AOF

    参考书籍<Redis设计与实现> 一丶为什么redis需要持久化 redis 作为一个内存数据库,如果不想办法将存储在内存中的数据,保存到磁盘中,那么一旦服务器进程退出,那么redis数据 ...

  9. [编程基础] C++多线程入门8-从线程返回值

    原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 8 从线程返回值 8 ...

  10. 原生js实现rsa加密

    原生js实现rsa加密 示例 createNewUserKey().then(function(keyPairs) { encrypt("this is origin text", ...