需求:要求将GLTF三维模型放到地图上展示,并且添加各种图标和线进行标注。

用CesiumJS地图库实现代码如下:

引入CesiumJS库

1、直接clone源码包,在index.html中引入,如下:

<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
<meta name="description" content="Create 3D models using glTF.">
<title>Chemical plant</title>
<script type="text/javascript" src="../../Cesium-1.77/Build/Cesium/Cesium.js"></script>
<link href="../../Cesium-1.77/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
</head> <body>
<div id="cesiumContainer"></div>

2、参考官网说明(https://www.cesium.com/docs/tutorials/cesium-and-webpack/)用npm安装

贴下package.json和webpack.config.js:

package.json

{
"name": "cesium-webpack-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "node_modules/.bin/webpack --config webpack.config.js",
"start": "node_modules/.bin/webpack serve --config webpack.config.js --open"
},
"author": "",
"license": "ISC",
"devDependencies": {
"cesium": "^1.78.0",
"copy-webpack-plugin": "^7.0.0",
"css-loader": "^5.0.2",
"html-webpack-plugin": "^5.2.0",
"style-loader": "^2.0.0",
"url-loader": "^4.1.1",
"webpack": "^5.23.0",
"webpack-cli": "^4.5.0",
"webpack-dev-server": "^3.11.2"
}
}

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin'); const cesiumSource = 'node_modules/cesium/Source';
const cesiumWorkers = '../Build/Cesium/Workers'; module.exports = {
context: __dirname,
entry: {
app: './src/index.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
sourcePrefix: ''
},
amd: {
toUrlUndefined: true
},
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}, {
test: /\.(png|gif|jpg|jpeg|svg|xml|json)$/,
use: ['url-loader']
}]
},
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
new CopyWebpackPlugin({
patterns: [
{ from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' },
{ from: path.join(cesiumSource, 'Assets'), to: 'Assets' },
{ from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' }
]
}),
new webpack.DefinePlugin({
CESIUM_BASE_URL: JSON.stringify('')
})
],
devServer: {
contentBase: path.join(__dirname, "dist")
},
resolve: {
alias: {
cesium: path.resolve(__dirname, cesiumSource)
},
fallback: {
fs: false
}
}
};

以上2种方式经测试都不需要在官网申请token,直接使用api即可。

初始化地图:

    const imageryProvider = new Cesium.UrlTemplateImageryProvider({
url: "http://webst01.is.autonavi.com/appmaptile?lang=zh_cn&style=7&x={x}&y={y}&z={z}",
tilingScheme: new Cesium.WebMercatorTilingScheme(),
fileExtension: 'png',
minimumLevel: 0,
maximumLevel: 20,
}); const viewer = new Cesium.Viewer("cesiumContainer", {
imageryProvider: imageryProvider,
animation: false, //是否显示动画控件
homeButton: false, //是否显示home键
geocoder: false, //是否显示地名查找控件,如果设置为true,则无法查询
baseLayerPicker: false, //是否显示图层选择控件
timeline: false, //是否显示时间线控件
fullscreenButton: false, //是否全屏显示
scene3DOnly: true, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
infoBox: false, //是否显示点击要素之后显示的信息
sceneModePicker: false, //是否显示投影方式控件 三维/二维
navigationInstructionsInitiallyVisible: false,
navigationHelpButton: false, //是否显示帮助信息控件
selectionIndicator: false, //是否显示指示器组件
}); viewer._cesiumWidget._creditContainer.style.display = "none"; //添加文字标注
viewer.imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({
url: "http://t0.tianditu.com/cva_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cva&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=TOKEN",
layer: "tdtAnnoLayer",
style: "default",
format: "image/jpeg",
tileMatrixSetID: "GoogleMapsCompatible",
show: false,
})); viewer.scene.primitives.add(Cesium.createOsmBuildings());
viewer.scene.highDynamicRange = false;
viewer.shadows = false;

    { //修改鼠标控制地图视图的默认行为:左键拖动,右键旋转
      viewer.scene.screenSpaceCameraController.zoomEventTypes = [
        Cesium.CameraEventType.WHEEL,
        Cesium.CameraEventType.MIDDLE_DRAG,
        Cesium.CameraEventType.PINCH,
      ];
      viewer.scene.screenSpaceCameraController.tiltEventTypes = [
        Cesium.CameraEventType.RIGHT_DRAG,
        Cesium.CameraEventType.PINCH,
        {
          eventType: Cesium.CameraEventType.RIGHT_DRAG,
          modifier: Cesium.KeyboardEventModifier.CTRL,
        },
        {
          eventType: Cesium.CameraEventType.MIDDLE_DRAG,
          modifier: Cesium.KeyboardEventModifier.CTRL,
        },
      ];
    }

    createGltfModel("../../data/gltf/NewFile.gltf", 117.628293, 23.798717, 0.0, {
modelScale: 1, //模型放大倍数
lightColor: new Cesium.Cartesian3(20.0, 20.0, 20.0), //模型的材质亮度
position: {
//地图初始化位置,坐标是3维笛卡尔坐标
x: -2707823.1735314624,
y: 5173260.303294086,
z: 2558159.506208664,
},
orientation: {
heading: 4.735189003200103,
pitch: -0.4113143959917751,
roll: 6.2804863005660785,
},
}); function createGltfModel(url, lng, lat, height, {
modelScale,
lightColor,
position,
orientation
} = {
modelScale: 1,
lightColor: new Cesium.Cartesian3(0, 0, 0),
position: { x: 0, y: 0, z: 0 },
orientation: { heading: 0, pitch: 0, roll: 0 }
}) {
viewer.entities.removeAll();
let ellipsoid = viewer.scene.globe.ellipsoid;
let cart3 = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(lng, lat, height));
let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(cart3);
let model = viewer.scene.primitives.add(Cesium.Model.fromGltf({
url,
modelMatrix,
scale: 1, //放大倍数
lightColor,//gltf模型加载后比较暗,这个起到增大模型材质亮度的作用
})); let initialPosition = new Cesium.Cartesian3(position.x, position.y, position.z); // 相机的位置
let homeCameraView = {
destination: initialPosition, // 相机的位置
orientation,
}; viewer.scene.camera.setView(homeCameraView); /**
* 这个时间是我调试的结果,模型不至于很暗
* 主要是时间要调到太阳照射到整个模型区域,日期没有多大影响
*/
let utc = Cesium.JulianDate.fromDate(new Date("2021/02/20 03:40:00"));//UTC
viewer.clock.currentTime = Cesium.JulianDate.addHours(utc, 8, new Cesium.JulianDate());
}

抗锯齿处理:

 //抗锯齿处理
{
viewer.scene.fxaa = true
viewer.scene.postProcessStages.fxaa.enabled = true;
let supportsImageRenderingPixelated = viewer.cesiumWidget._supportsImageRenderingPixelated;
if (supportsImageRenderingPixelated) {
let vtxf_dpr = window.devicePixelRatio;
while (vtxf_dpr >= 2.0) { vtxf_dpr /= 2.0; }
viewer.resolutionScale = vtxf_dpr;
}
}

添加图片:

 //添加图片
{
const iconMarks = [
{
id: 'factory1',
position: [117.62514171688602, 23.800514411219126, 40],
image: '../../data/icons/废气-C.png',
},
{
id: 'factory2',
position: [117.62441672316956, 23.801488899527932, 40],
image: '../../data/icons/废气-C.png',
},
{
id: 'camera1',
position: [117.62438331048037, 23.80172986514075, 20],
image: '../../data/icons/摄像头-C.png',
width: 13,
height: 18
},
{
id: 'camera2',
position: [117.6251283858732, 23.801983468675637, 10],
image: '../../data/icons/摄像头-C.png',
width: 13,
height: 18
}
]; for (const mark of iconMarks) {
let width = mark.width || 30;
let height = mark.height || 30;
viewer.entities.add({
id: mark.id,
name: 'mark',
position: Cesium.Cartesian3.fromDegrees(...mark.position),
billboard: {
// 图像地址,URI或Canvas的属性
image: mark.image,
// 设置颜色和透明度
// color: Cesium.Color.WHITE.withAlpha(1),
// 高度(以像素为单位)
height,
// 宽度(以像素为单位)
width,
// 逆时针旋转
rotation: 0,
// 大小是否以米为单位
sizeInMeters: false,
// 相对于坐标的垂直位置
verticalOrigin: Cesium.VerticalOrigin.CENTER,
// 相对于坐标的水平位置
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
// 该属性指定标签在屏幕空间中距此标签原点的像素偏移量
pixelOffset: new Cesium.Cartesian2(-width / 2, -height / 2),
// 应用于图像的统一比例。比例大于会1.0放大标签,而比例小于会1.0缩小标签。
scale: 1.0,
// 是否显示
show: true
}
});
}
}

添加线:

 //添加线
{
const markLines = [
{
id: 'line1',
positions: [[117.62514171688602, 23.800514411219126, 0], [117.62514171688602, 23.800514411219126, 40]],
},
{
id: 'line2',
positions: [[117.62441672316956, 23.801488899527932, 0], [117.62441672316956, 23.801488899527932, 40]],
},
{
id: 'line3',
positions: [[117.62441672316956, 23.801488899527932, 20],
[117.62438331048037, 23.80172986514075, 20],
[117.6251283858732, 23.801983468675637, 10],
[117.62516689671625, 23.802117335288763, 10]]
}
]; for (const line of markLines) {
let polyline = new Cesium.PolylineGraphics();
polyline.material = new Cesium.ColorMaterialProperty(new Cesium.Color(0.18, 0.67, 1, 1));
polyline.width = new Cesium.ConstantProperty(2);
polyline.arcType = new Cesium.ConstantProperty(
Cesium.ArcType.NONE
);
let coordArr = line.positions.map(e => Cesium.Cartesian3.fromDegrees(...e));
console.log('coordArr', coordArr);
polyline.positions = new Cesium.ConstantProperty(coordArr);
let entity = new Cesium.Entity({
id: line.id,
show: true,
polyline,
name: 'line',
});
viewer.entities.add(entity);
}
}

添加事件:

//事件
{
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (evt) {
let pick = viewer.scene.pick(evt.position);
// //选中某模型
if (pick && pick.id) {
alert(pick.id._id)
}
let cartesian = viewer.camera.pickEllipsoid(evt.position, viewer.scene.globe.ellipsoid);
let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
let lng = Cesium.Math.toDegrees(cartographic.longitude);//经度值
let lat = Cesium.Math.toDegrees(cartographic.latitude);//纬度值
let mapPosition = { x: lng, y: lat, z: cartographic.height };//cartographic.height的值始终为零。
// console.log('mapPosition: ', mapPosition);
console.log('lng: ', lng, 'lat: ', lat);//拾取坐标 }, Cesium.ScreenSpaceEventType.LEFT_CLICK); handler.setInputAction(evt => {
let pick = viewer.scene.pick(evt.endPosition);
//选中某模型
if (pick && pick.id && pick.id._name === 'mark') {
// console.log('pick', pick.id._id);
// 修改鼠标指针样式
viewer._container.style.cursor = 'pointer'; } else {
viewer._container.style.cursor = '';
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
}

效果:

Cesium开发三维地图入门的更多相关文章

  1. 【转载】Excel 三维地图入门

    三维地图入门(office 2016) https://support.office.com/zh-cn/article/%E4%B8%89%E7%BB%B4%E5%9C%B0%E5%9B%BE%E5 ...

  2. 用three.js开发三维地图实例

    公司要做智慧消防楼层可视化,需要用到web3d,开源的引擎中先研究了cesium三维地球,但cesium做楼层感觉是大材小用,而且体验也不好,最终选用的是功能强大.更适合小型场景的three. thr ...

  3. 使用ESMap的地图平台开发三维地图

      本文简单的介绍使用ESmap的SDK开发(DIY自己地图的)一个地图的过程.若有不足,欢迎指正. 一.创建地图 只需四步,从无到有,在浏览器中创建一个自己的三维地图,炫酷到爆! 第一步:引入ESM ...

  4. [原创.数据可视化系列之二]使用cesium三维地图展示美国全球军事基地分布

    基于浏览器的三维地图还算是一个比较高冷的东西,最主要的技术难点是如何在浏览器上 多快好省 的显示三维数据,很遗憾,还真的没有太好的的方案,只能说还有可行的方案. 很久之前用过skyline,使用CS居 ...

  5. 如何使用JS来开发室内三维地图的轨迹回放功能

     在制作完成室内三维地图的功能后,最经常有的需求就是如何做人员的轨迹回放,一般流程都是从数据库中查询轨迹坐标后,经过后台查询接口返回给前端,接下来的事情都交给JS来完成. 如果想做好一个性能好的轨迹回 ...

  6. SkylineGlobe 7.0.1 & 7.0.2版本Web开发 如何正确使用三维地图控件和工程树控件

    Skyline TerraExplorer Pro目前正式发布的7.0.1&7.0.2版本,还只是64位的版本, 在Web开发的时候,如何在页面中正确嵌入三维地图控件,让一些小伙伴凌乱了. 下 ...

  7. 【三维地图】开发攻略 —— 详解“GeoJSON”技术和应用场景

    GeoJSON ,一个用于存储地理信息的数据格式.GoeJSON对象可以表示几何.特征或特征集合,支持:点.线.面.多点.多线.多面和几何集合.在基于平面地图,三维地图中都需要用到的一种数据类型. 由 ...

  8. Supermap/Cesium 开发心得----动态散点图(波纹点/涟漪点)

    在二维开发中,openlayers4 入门开发系列结合 echarts4 实现散点图,下图是GIS之家的效果图,那么在三维中,则可借助Entity来变相构造下图的效果. 思路: 构造实体ellipse ...

  9. [置顶] Xamarin android如何调用百度地图入门示例(一)

    在Xamarin android如何调用百度地图呢? 首先我们要区分清楚,百度地图这是一个广泛的概念,很多刚刚接触这个名词"百度地图api",的确是泛泛而谈,我们来看一下百度地图的 ...

  10. Cesium学习2:如何从零开始在Eclipse IDE,Java语言搭建cesium开发环境

    废话不多说,今天就先在Eclipse上搭建Cesium开发环境吧~ 零.Cesium简介 Cesiumjs 是一套javascript库,用来渲染3D地球,2D区域地图,和多种GIS要素.不需要安装任 ...

随机推荐

  1. 【GDKOI 2021提高组DAY2】抄写

    \(\text{Solution}\) \(dp\) 翻折就只需预处理回文中心 \(Manacher\) 预处理即可 \(Code\) #include<cstdio> #include& ...

  2. VSCode 国内镜像下载地址

    https://vscode.cdn.azure.cn/stable/,比如: https://vscode.cdn.azure.cn/stable/e4503b30fc78200f846c62cf8 ...

  3. 基于C++的OpenGL 12 之多光源

    1. 引言 本文基于C++语言,描述OpenGL的多光源 前置知识可参考: 基于C++的OpenGL 11 之投光物 - 当时明月在曾照彩云归 - 博客园 (cnblogs.com) 笔者这里不过多描 ...

  4. global与nonlocal关键字、函数名的多种用法、函数的嵌套调用、函数的嵌套定义、闭包函数、装饰器简介

    目录 一.global与nonlocal关键字 二.函数名的多种用法 三.函数的嵌套调用 四.函数的嵌套定义 五.闭包函数 六.装饰器简介 一.global与nonlocal关键字 global方法: ...

  5. AOP中的一些重要术语简介

    AOP的定义:AOP(Aspect Oriented Progamming)利用称为"横切"的技术,剖解开封装的对象内部,把多个类的公共行为封装到一个可重用模块中,便于减少重复代码 ...

  6. js获取input处理

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. classmethod 修饰符

    title: Python classmethod 修饰符 author: 杨晓东 permalink: classmethod date: 2021-10-02 11:27:04 categorie ...

  8. Vue的watch观察xxx.xx.xx点出属性值的解决办法

    解决办法 使用引号引起来,如: watch: { '$route.params.value'(newValue) { ... } }

  9. k8s网路策略

    Network Policy(网络策略) 默认情况下,k8s集群网络是没有任何限制的,Pod可以和任何其他Pod通信,在某些场景下需要做网络控制,减少网络面的攻击,提高安全性,就会用到网络策略(Net ...

  10. Oracle 查看表空间使用率

    SELECT Upper(F.TABLESPACE_NAME) "TablespaceName", D.TOT_GROOTTE_MB "Total(M)", D ...