开篇寄语
好久没分享地图相关的内容了,本篇文章就来介绍一个可以让 3D 模型出现在地球上的库——CesiumJS,结合天地图来实现,那么该如何实现呢?效果如封面图所示,请看本篇文章。
前情提要
准备要素
- CesiumJS,前往该官网注册,获取token
- 天地图,前往该官网注册,获取token
- 香港规划署实景三维模型,前往该官网下载想要的 3D 模型
内容详情
准备好以上这些,可以将下面的代码复制粘贴到你的比如 VScode 之类的代码编辑器,将 Cesium Token 和 天地图的 Token 替换成自己的,然后运行就可以了,完整代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <!-- Include the CesiumJS JavaScript and CSS files --> <script src="https://unpkg.com/[email protected]/Build/Cesium/Cesium.js"></script> <link href="https://unpkg.com/[email protected]/Build/Cesium/Widgets/widgets.css" rel="stylesheet" /> <script src="https://api.tianditu.gov.cn/cdn/plugins/cesium/cesiumTdt.js"></script> <style> html, body, #cesiumContainer { padding: 0; margin: 0; height: 100%; } #zoomToTileset { left: 20px; top: 20px; position: absolute; z-index: 2 } </style> </head> <body> <button id="zoomToTileset">跳转到九龙</button> <div id="cesiumContainer"></div> <script> // Your access token can be found at: https://ion.cesium.com/tokens. // This is the default access token from your ion account Cesium.Ion.defaultAccessToken = '你的CesiumJS的token'; const token = "你的天地图的token" var tdtUrl = 'https://t{s}.tianditu.gov.cn/' var subdomains = ['0', '1', '2', '3', '4', '5', '6', '7'] // Initialize the Cesium Viewer in the HTML element with the `cesiumContainer` ID. const viewer = new Cesium.Viewer('cesiumContainer', { terrainProvider: Cesium.createWorldTerrain(), animation: false, //是否创建动画小器件,左下角仪表 baseLayerPicker: false, //是否显示图层选择器 fullscreenButton: true, //是否显示全屏按钮 geocoder: false, //是否显示geocoder小器件,右上角查询按钮 homeButton: false, //是否显示Home按钮 infoBox: false, //是否显示信息框 sceneModePicker: false, //是否显示3D/2D选择器 selectionIndicator: false, //是否显示选取指示器组件 timeline: false, //是否显示时间轴 navigationHelpButton: false //是否显示右上角的帮助按钮 }); // Create the tileset in the viewer const tileset = viewer.scene.primitives.add( new Cesium.Cesium3DTileset({ url: "./dataTwo/tileset.json", projectionTransform: new Cesium.WebMercatorProjection() }) ); tileset.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame( Cesium.Cartesian3.fromDegrees(120, 40, 0.0) ); viewer.zoomTo(tileset); viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(114.16109523122268,22.289904950356182, 2000), orientation: { heading: Cesium.Math.toRadians(-90), pitch: Cesium.Math.toRadians(-105), roll: 0.0 } }); const zoomToTilesetButton = document.getElementById("zoomToTileset"); zoomToTilesetButton.addEventListener("click", function () { viewer.zoomTo(tileset); }); let heightOffset = 0; viewer.scene.preUpdate.addEventListener(function () { heightOffset = 0; const transform = Cesium.Matrix4.fromTranslation( new Cesium.Cartesian3(0, 0, heightOffset) ); tileset.modelMatrix = transform; }); const point = viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(114.16199523122268,22.283304950356182), point: { pixelSize: 10, color: Cesium.Color.YELLOW } }); //去除版权信息 viewer._cesiumWidget._creditContainer.style.display = "none"; // //点击获取光标所在的经纬度 // var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); // handler.setInputAction(function (click) { // var cartesian = viewer.camera.pickEllipsoid(click.position, viewer.scene.globe.ellipsoid); // if (cartesian) { // var cartographic = Cesium.Cartographic.fromCartesian(cartesian); // var longitude = Cesium.Math.toDegrees(cartographic.longitude); // var latitude = Cesium.Math.toDegrees(cartographic.latitude); // console.log(longitude, latitude); // } // }, Cesium.ScreenSpaceEventType.LEFT_CLICK); // 叠加影像服务 var imgMap = new Cesium.UrlTemplateImageryProvider({ url: tdtUrl + "DataServer?T=img_w&x={x}&y={y}&l={z}&tk=" + token, subdomains: subdomains, tilingScheme: new Cesium.WebMercatorTilingScheme(), maximumLevel: 18 }); viewer.imageryLayers.addImageryProvider(imgMap); // 叠加国界服务 var iboMap = new Cesium.UrlTemplateImageryProvider({ url: tdtUrl + "DataServer?T=ibo_w&x={x}&y={y}&l={z}&tk=" + token, subdomains: subdomains, tilingScheme: new Cesium.WebMercatorTilingScheme(), maximumLevel: 10 }); viewer.imageryLayers.addImageryProvider(iboMap); // 叠加地形服务 var terrainUrls = new Array(); for (var i = 0; i < subdomains.length; i++) { var url = tdtUrl.replace("{s}", subdomains[i]) + "mapservice/swdx?tk=" + token; terrainUrls.push(url); } var provider = new Cesium.GeoTerrainProvider({ urls: terrainUrls }); viewer.terrainProvider = provider; // 叠加三维地名服务 var wtfs = new Cesium.GeoWTFS({ viewer, subdomains: subdomains, metadata: { boundBox: { minX: -180, minY: -90, maxX: 180, maxY: 90 }, minLevel: 1, maxLevel: 20 }, aotuCollide: true, //是否开启避让 collisionPadding: [5, 10, 8, 5], //开启避让时,标注碰撞增加内边距,上、右、下、左 serverFirstStyle: true, //服务端样式优先 labelGraphics: { font: "28px sans-serif", fontSize: 28, fillColor: Cesium.Color.WHITE, scale: 0.5, outlineColor: Cesium.Color.BLACK, outlineWidth: 5, style: Cesium.LabelStyle.FILL_AND_OUTLINE, showBackground: false, backgroundColor: Cesium.Color.RED, backgroundPadding: new Cesium.Cartesian2(10, 10), horizontalOrigin: Cesium.HorizontalOrigin.MIDDLE, verticalOrigin: Cesium.VerticalOrigin.TOP, eyeOffset: Cesium.Cartesian3.ZERO, pixelOffset: new Cesium.Cartesian2(0, 8) }, billboardGraphics: { horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.CENTER, eyeOffset: Cesium.Cartesian3.ZERO, pixelOffset: Cesium.Cartesian2.ZERO, alignedAxis: Cesium.Cartesian3.ZERO, color: Cesium.Color.WHITE, rotation: 0, scale: 1, width: 18, height: 18 } }); //三维地名服务,使用wtfs服务 wtfs.getTileUrl = function () { return tdtUrl + "mapservice/GetTiles?lxys={z},{x},{y}&tk=" + token; }; wtfs.initTDT([ { x: 6, y: 1, level: 2, boundBox: { minX: 90, minY: 0, maxX: 135, maxY: 45 } }, { x: 7, y: 1, level: 2, boundBox: { minX: 135, minY: 0, maxX: 180, maxY: 45 } }, { x: 6, y: 0, level: 2, boundBox: { minX: 90, minY: 45, maxX: 135, maxY: 90 } }, { x: 7, y: 0, level: 2, boundBox: { minX: 135, minY: 45, maxX: 180, maxY: 90 } }, { x: 5, y: 1, level: 2, boundBox: { minX: 45, minY: 0, maxX: 90, maxY: 45 } }, { x: 4, y: 1, level: 2, boundBox: { minX: 0, minY: 0, maxX: 45, maxY: 45 } }, { x: 5, y: 0, level: 2, boundBox: { minX: 45, minY: 45, maxX: 90, maxY: 90 } }, { x: 4, y: 0, level: 2, boundBox: { minX: 0, minY: 45, maxX: 45, maxY: 90 } }, { x: 6, y: 2, level: 2, boundBox: { minX: 90, minY: -45, maxX: 135, maxY: 0 } }, { x: 6, y: 3, level: 2, boundBox: { minX: 90, minY: -90, maxX: 135, maxY: -45 } }, { x: 7, y: 2, level: 2, boundBox: { minX: 135, minY: -45, maxX: 180, maxY: 0 } }, { x: 5, y: 2, level: 2, boundBox: { minX: 45, minY: -45, maxX: 90, maxY: 0 } }, { x: 4, y: 2, level: 2, boundBox: { minX: 0, minY: -45, maxX: 45, maxY: 0 } }, { x: 3, y: 1, level: 2, boundBox: { minX: -45, minY: 0, maxX: 0, maxY: 45 } }, { x: 3, y: 0, level: 2, boundBox: { minX: -45, minY: 45, maxX: 0, maxY: 90 } }, { x: 2, y: 0, level: 2, boundBox: { minX: -90, minY: 45, maxX: -45, maxY: 90 } }, { x: 0, y: 1, level: 2, boundBox: { minX: -180, minY: 0, maxX: -135, maxY: 45 } }, { x: 1, y: 0, level: 2, boundBox: { minX: -135, minY: 45, maxX: -90, maxY: 90 } }, { x: 0, y: 0, level: 2, boundBox: { minX: -180, minY: 45, maxX: -135, maxY: 90 } } ]); </script> </div> </body> </html>
温馨提示
天地图使用的 CensiumJS 有版本需求,推荐使用版本为 1.63.1,切记,切记。
- 我的微信
- 微信扫一扫加好友
- 我的微信公众号
- 扫描关注公众号