Mars3D与第三方集成 您所在的位置:网站首页 apidemo注册 Mars3D与第三方集成

Mars3D与第三方集成

2023-02-28 15:31| 来源: 网络整理| 查看: 265

1. 引言

Mars3D是基于Cesium的Web端的三维GIS库,对Cesium做了进一步封装和扩展

Mars3D官网:Mars3D三维可视化平台 | 火星科技

Mars3D开发手册:开发教程 - Mars3D三维可视化平台 | 火星科技

GitHub地址:Mars3D三维可视化平台 | 火星科技

API文档:API文档 - Mars3D三维可视化平台 | 火星科技

以下是一些Mars3D与一些第三方库集成的使用案例

2. 集成示例 2.1 Turf

Turf客户端分析库,【需要引入Turf库】

将数据转换为GeoJson对象并使用Turf进行分析

Document html, body, .mars3d-container { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; } let mapOptions = { basemaps: [{ name: "天地图", type: "tdt", layer: "img_d", show: true }], } const map = new mars3d.Map("mars3dContainer", mapOptions) map.setSceneOptions({ center: { lat: 31.72076, lng: 117.033888, alt: 223798, heading: 0, pitch: -45 } }) // 创建矢量数据图层 const geoJsonLayer = new mars3d.layer.GeoJsonLayer({ url: "https://openlayers.org/en/latest/examples/data/geojson/roads-seoul.geojson", symbol: { type: "polyline", styleOptions: { color: "#f00", width: 4 } }, flyTo: true }) map.addLayer(geoJsonLayer) //绑定监听事件 geoJsonLayer.on(mars3d.EventType.load, function (event) { console.log('矢量数据对象加载完成', event) const geojson = geoJsonLayer.toGeoJSON() console.log(geojson) const buffered = turf.buffer(geojson, 25, { units: 'meters' }) console.log(buffered) const bufferedLayer = new mars3d.layer.GeoJsonLayer({ data: buffered, symbol: { type: "polygon", styleOptions: { color: "#0ff" } }, flyTo: true }) map.addLayer(bufferedLayer) })

image-20230207231621086

2.2 MapV new mars3d.layer.MapVLayer(options, dataSet)

MapV图层 【需要引入 mapv.js 库 和 mars3d-mapv 插件库】

Document html, body, .mars3d-container { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; } let mapOptions = { basemaps: [{ name: "天地图", type: "tdt", layer: "img_d", show: true }], } const map = new mars3d.Map("mars3dContainer", mapOptions) map.setSceneOptions({ center: { lat: 31.72076, lng: 117.033888, alt: 223798, heading: 0, pitch: -45 } }) // 构造数据 let positions = [] let geojson = [] let randomCount = 300 while (randomCount--) { // 取区域内的随机点 let point = [random(113 * 1000, 119 * 1000) / 1000, random(28 * 1000, 35 * 1000) / 1000] positions.push(Cesium.Cartesian3.fromDegrees(point[0], point[1])) geojson.push({ geometry: { type: "Point", coordinates: point }, count: 30 * Math.random() }) } console.log(geojson) map.camera.flyTo({ destination: Cesium.Rectangle.fromCartesianArray(positions) }) // mapv图层参数 let options = { fillStyle: "rgba(55, 50, 250, 0.8)", shadowColor: "rgba(255, 250, 50, 1)", shadowBlur: 20, max: 100, size: 50, label: { show: true, fillStyle: "white" }, globalAlpha: 0.5, gradient: { 0.25: "rgb(0,0,255)", 0.55: "rgb(0,255,0)", 0.85: "yellow", 1.0: "rgb(255,0,0)" }, draw: "honeycomb", data: geojson // 数据 } // 创建MapV图层 const mapVLayer = new mars3d.layer.MapVLayer(options) map.addLayer(mapVLayer) mapVLayer.on("click", function (event) { console.log("单击了图层", event) }) function random(min, max) { return Math.floor(Math.random() * (max - min + 1) + min) }

image-20230207232659612

2.3 Echarts new mars3d.layer.EchartsLayer(options)

Echarts图层, 【需要引入 echarts 库 和 mars3d-echarts 插件库】

Document html, body, .mars3d-container { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; } let mapOptions = { basemaps: [{ name: "天地图", type: "tdt", layer: "img_d", show: true }], } const map = new mars3d.Map("mars3dContainer", mapOptions) map.setSceneOptions({ center: { lat: 30.589203, lng: 120.732051, alt: 18446, heading: 2, pitch: -49 } }) mars3d.Util.fetchJson({ url: "//data.mars3d.cn/file/apidemo/lineroad.json" }) .then(function (json) { let options = { animation: false, visualMap: { type: "piecewise", left: "right", bottom: 46, min: 0, max: 15, splitNumber: 5, maxOpen: true, color: ["red", "yellow", "green"], textStyle: { color: "#ffffff" } }, tooltip: { formatter: function (params, ticket, callback) { return "拥堵指数:" + params.value }, trigger: "item" }, series: [ { type: "lines", coordinateSystem: "mars3dMap", polyline: true, data: json.data, lineStyle: { normal: { opacity: 1, width: 4 }, emphasis: { width: 6 } }, effect: { show: true, symbolSize: 2, color: "white" } } ] } const echartsLayer = new mars3d.layer.EchartsLayer(options) map.addLayer(echartsLayer) })

image-20230208101504970

2.4 ThreeJS

ThreeJS集成,这里使用了官方示例的集成代码,【需要引入Three JS库和集成代码】

集成代码如下:

const BaseLayer = mars3d.layer.BaseLayer const THREE = window.THREE // 与THREE.js集成 class ThreeLayer extends BaseLayer { constructor(options = {}) { super(options) this._pointerEvents = this.options.pointerEvents } _showHook(show) { if (show) { this._threejsContainer.style.visibility = "visible" } else { this._threejsContainer.style.visibility = "hidden" } } /** * 对象添加到地图前创建一些对象的钩子方法, * 只会调用一次 * @return {void} 无 * @private */ _mountedHook() { if (!THREE) { throw new Error("请引入 three.js 库 ") } const scene = this._map.scene const threeContainer = mars3d.DomUtil.create("div", "mars3d-threejs") threeContainer.style.position = "absolute" threeContainer.style.top = "0px" threeContainer.style.left = "0px" threeContainer.style.width = scene.canvas.clientWidth + "px" threeContainer.style.height = scene.canvas.clientHeight + "px" threeContainer.style.pointerEvents = this._pointerEvents ? "auto" : "none" // auto时可以交互,但是没法放大地球, none 没法交互 this._container = threeContainer const fov = 45 const aspect = scene.canvas.clientWidth / scene.canvas.clientHeight const near = 1 const far = 10 * 1000 * 1000 // needs to be far to support Cesium's world-scale rendering this.scene = new THREE.Scene() this.camera = new THREE.PerspectiveCamera(fov, aspect, near, far) this.renderer = new THREE.WebGLRenderer({ alpha: true }) threeContainer.appendChild(this.renderer.domElement) } /** * 对象添加到地图上的创建钩子方法, * 每次add时都会调用 * @return {void} 无 * @private */ _addedHook() { if (this._container) { this._map.container.appendChild(this._container) } this._map.viewer.useDefaultRenderLoop = false // 关闭自动渲染 // eslint-disable-next-line const that = this ;(function frame() { // animateFrame: requestAnimationFrame事件句柄,用来清除操作 that._animateFrame = window.requestAnimationFrame(frame) that.update() // 按帧率执行 })() } /** * 对象从地图上移除的创建钩子方法, * 每次remove时都会调用 * @return {void} 无 * @private */ _removedHook() { window.cancelAnimationFrame(this._animateFrame) delete this._animateFrame this._map.viewer.useDefaultRenderLoop = true if (this._container) { this._map.container.removeChild(this._container) } } update() { this.renderCesium() this.renderThreeObj() this.renderCamera() } renderCesium() { this._map.viewer.render() } renderThreeObj() { const width = this._container.clientWidth const height = this._container.clientHeight this.renderer.setSize(width, height) this.renderer.render(this.scene, this.camera) } renderCamera() { // register Three.js scene with Cesium this.camera.fov = Cesium.Math.toDegrees(this._map.camera.frustum.fovy) // ThreeJS FOV is vertical this.camera.updateProjectionMatrix() // Clone Cesium Camera projection position so the // Three.js Object will appear to be at the same place as above the Cesium Globe this.camera.matrixAutoUpdate = false this.camera.lookAt(new THREE.Vector3(0, 0, 0)) const cvm = this._map.camera.viewMatrix const civm = this._map.camera.inverseViewMatrix this.camera.matrixWorld.set( civm[0], civm[4], civm[8], civm[12], civm[1], civm[5], civm[9], civm[13], civm[2], civm[6], civm[10], civm[14], civm[3], civm[7], civm[11], civm[15] ) this.camera.matrixWorldInverse.set( cvm[0], cvm[4], cvm[8], cvm[12], cvm[1], cvm[5], cvm[9], cvm[13], cvm[2], cvm[6], cvm[10], cvm[14], cvm[3], cvm[7], cvm[11], cvm[15] ) const width = this._map.scene.canvas.clientWidth const height = this._map.scene.canvas.clientHeight this.camera.aspect = width / height this.renderer.setSize(width, height) this.camera.updateProjectionMatrix() this.renderer.clear() this.renderer.render(this.scene, this.camera) } }

示例代码文件:

Document html, body, .mars3d-container { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; } let mapOptions = { basemaps: [{ name: "天地图", type: "tdt", layer: "img_d", show: true }], } const map = new mars3d.Map("mars3dContainer", mapOptions) map.setSceneOptions({ center: { lat: 30.980053, lng: 117.375049, alt: 110976, heading: 357, pitch: -50 } }) const threeLayer = new ThreeLayer() map.addLayer(threeLayer) let minWGS84 = [117.142184, 31.869697] let maxWGS84 = [117.357015, 31.713898] let ce = Cesium.Cartesian3.fromDegrees((minWGS84[0] + maxWGS84[0]) / 2, (minWGS84[1] + maxWGS84[1]) / 2 - 1, 200000) let geometry = new THREE.SphereGeometry(1, 32, 32) const sphere = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial({ color: 0xffffff, side: THREE.DoubleSide })) // 12面体 // translate "up" in Three.js space so the "bottom" of the mesh is the handle sphere.scale.set(5000, 5000, 5000) sphere.uuid = "sphere" const sphereYup = new THREE.Group() sphereYup.add(sphere) threeLayer.scene.add(sphereYup) // don’t forget to add it to the Three.js scene manually sphereYup.position.set(ce.x, ce.y, ce.z) let arrXdObj = [] let xdObj = new XDObject() xdObj.threeMesh = sphereYup xdObj.minWGS84 = minWGS84 xdObj.maxWGS84 = maxWGS84 arrXdObj.push(xdObj) geometry = new THREE.DodecahedronGeometry() const dodecahedronMesh = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial()) // 12面体 dodecahedronMesh.scale.set(5000, 5000, 5000) dodecahedronMesh.position.z += 15000 // translate "up" in Three.js space so the "bottom" of the mesh is the handle dodecahedronMesh.rotation.x = Math.PI / 2 // rotate mesh for Cesium's Y-up system dodecahedronMesh.uuid = "12面体" const dodecahedronMeshYup = new THREE.Group() dodecahedronMeshYup.add(dodecahedronMesh) threeLayer.scene.add(dodecahedronMeshYup) // don’t forget to add it to the Three.js scene manually dodecahedronMeshYup.position.set(ce.x, ce.y, ce.z) // Assign Three.js object mesh to our object array xdObj = new XDObject() xdObj.threeMesh = dodecahedronMeshYup xdObj.minWGS84 = minWGS84 xdObj.maxWGS84 = maxWGS84 arrXdObj.push(xdObj) // 添加灯光,点光源 const spotLight = new THREE.SpotLight(0xffffff) spotLight.position.set(0, 0, 50000) spotLight.castShadow = true // 设置光源投射阴影 spotLight.intensity = 1 sphereYup.add(spotLight) // 添加环境光 const hemiLight = new THREE.HemisphereLight(0xff0000, 0xff0000, 1) sphereYup.add(hemiLight) let cartToVec = function (cart) { return new THREE.Vector3(cart.x, cart.y, cart.z) } // Configure Three.js meshes to stand against globe center position up direction for (var id in arrXdObj) { minWGS84 = arrXdObj[id].minWGS84 maxWGS84 = arrXdObj[id].maxWGS84 // convert lat/long center position to Cartesian3 let center = Cesium.Cartesian3.fromDegrees((minWGS84[0] + maxWGS84[0]) / 2, (minWGS84[1] + maxWGS84[1]) / 2) // get forward direction for orienting model let centerHigh = Cesium.Cartesian3.fromDegrees((minWGS84[0] + maxWGS84[0]) / 2, (minWGS84[1] + maxWGS84[1]) / 2, 1) // use direction from bottom left to top left as up-vector let bottomLeft = cartToVec(Cesium.Cartesian3.fromDegrees(minWGS84[0], minWGS84[1])) let topLeft = cartToVec(Cesium.Cartesian3.fromDegrees(minWGS84[0], maxWGS84[1])) let latDir = new THREE.Vector3().subVectors(bottomLeft, topLeft).normalize() // configure entity position and orientation arrXdObj[id].threeMesh.position.copy(center) arrXdObj[id].threeMesh.lookAt(centerHigh) arrXdObj[id].threeMesh.up.copy(latDir) } function XDObject() { this.threeMesh = null this.minWGS84 = null this.maxWGS84 = null }

image-20230208103002385

3. 参考资料

[1]功能示例(Vue版) - Mars3D三维可视化平台 | 火星科技

[2]API文档 - Mars3D三维可视化平台 | 火星科技

[3]开发教程 - Mars3D三维可视化平台 | 火星科技



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有