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. ArcObjects SDK开发 014 MapSurround和普通Element

    1.如何获取MapSurround 和获取MapFrame类似,如果你已经获取指北针.比例尺等对象,可以通过IGraphicsContainer的FindFrame函数获取.如果没有,则通过IGrap ...

  2. TabControl控件的简单使用-添加tab

    1.首先创建一个MFC对话框框架,在对话框资源上从工具箱中添加上一个Tab Control 控件,根据需要修改一下属性,然后右击控件,为这个控件添加一个变量,将此控件跟一个CTabCtrl类变量绑定在 ...

  3. 互斥锁 线程理论 GIL全局解释器锁 死锁现象 信号量 event事件 进程池与线程池 协程实现并发

    目录 互斥锁 multiprocessing Lock类 锁的种类 线程理论 进程和线程对比 开线程的两种方式(类似进程) 方式1 使用Thread()创建线程对象 方式2 重写Thread类run方 ...

  4. Windows搭建Git服务器

    Windows如何搭建Git服务器 1.安装java环境 (1)下载安装java 注意(java的版本需要在1.7及以上) (2)配置java的环境变量 (3)检验java环境是否安装成功 2.下载安 ...

  5. Introduction & Directory

    一个日常划水的高中生而已啦,我不会承认这个博客的CSS是copy的 一个貌似并不准确的图-- <算法竞赛进阶指南>学习: 动态规划: DP经典例题--LIS&LCS 洛谷题解: 搜 ...

  6. $_GET方法踩坑

    背景 写代码时,遇到一个奇怪的问题:小程序卡券解码接口老是报解码失败,苦寻了一个小时,发现原来是url参数经过thinkphp的I方法被过滤掉,而且涉及到PHP原生的$_GET 原因 I方法底层是原生 ...

  7. MongoDB - 副本集简介

    简介 在 MongoDB 中,副本集指的是一组 MongoDB 服务器实例掌管同一个数据集,实例可以在不同的机器上. 其中一个用于处理写操作的是主节点(Primary),还有多个用于保存主节点的数据副 ...

  8. Centos下部署最后一版支持Docker的k8s集群

    部署版本 首先要确定部署的版本 查询Kubernetes对Docker支持的情况 kubernetes/dependencies.yaml at master · kubernetes/kuberne ...

  9. [MySQL] 索引的使用、SQL语句优化策略

    目录 索引 什么是索引 索引的创建与删除 创建索引 删除索引 索引的使用 使用explain分析SQL语句 最佳左前缀 索引覆盖 避免对索引列进行额外运算 SQL语句优化 小表驱动大表 索引 什么是索 ...

  10. 《Effective C++》构造、析构、赋值运算

    Item 05:了解C++默默编写并调用了哪些函数 总结:编译器可以暗自为class创建default 构造函数.copy构造函数.copy assignment操作符,以及析构函数. (这一小节比较 ...