/** * 创建者:王成 * 创建日期:2021年11月8日 * 描述:Cesium三维图层 */ /** * 标注层标识 */ var labelFlag = "_label"; /** * 绘制模式 包括点 线 面 矩形 点 空 */ var ActionType = { measureLength: 'measureLength', //测量长度动作 measureArea: 'measureArea', //测量面积动作 queryAttribute: 'queryAttribute', //查询属性动作 clipBIM: 'clipBIM', //切割BIM模型动作 flightAround: 'flightAround', //环绕飞行 non: 'non', //null动作 casePointQuery: 'casePointQuery', //案件点查询 casePolygonQuery: 'casePolygonQuery', //案件区域查询 } /** * 构造函数 * @param {JSON} options 选项 */ function CrMap(options) { this._init(options); } /** * 原型设置 必须的 * @param {JSON} options 选项 */ CrMap.prototype.extend = function(options) { for (var key in options) { CrMap.prototype[key] = options[key]; } } /** * 私有函数集合 */ CrMap.prototype.extend({ /** * 初始化函数 * @param {JSON} options 选项 */ _init: function(options) { if (options.selector == undefined) { console.error('未设置地图容器!') return; } //局部变量 this.selector = options.selector; //3D地图容器 this.serverUrl = options.serverUrl; this.viewer = undefined; //地图 //事件 this.onMouseMove = options.onMouseMove; //鼠标移动事件 this.onShowTooltip = options.onShowTooltip; //显示移动弹窗回调 this.onQueryVectorResult = options.onQueryVectorResult; //矢量数据查询回调 this.onQueryStart = options.onQueryStart; //查询开始回调 this.onExtentChange = options.onExtentChange; //地图范围变化事件 this.onPostSceneChange = options.onPostSceneChange; //场景变化后事件 this.onPopoverQueryTool = options.onPopoverQueryTool; //查询工具 此处指案件 /* 属性查询相关 */ this.queryLayers = []; //查询图层数组 this.attributesQueryIndex = 0; //服务图层查询索引 this.attributesData = []; //属性查询的数据 this.rightInfoIndex = undefined; this.attributesEntity = []; //Entity查询的内容 需要与attributesData中保持一致 //全局变量 this.beforeLayerIds = []; //预知的图层Id集合 如果是后添加图层 则必须告知该参数 this.imageryLayers = undefined; //图层数组 this.primitives = undefined; //原语集合 this.entities = undefined; //实体集合 this.dataSources = undefined; //数据源数组 //切割相关 this.planeTargetY = 30; //ClippingPlane距离原点的距离 this.planeSelected = undefined; // 鼠标选中的ClippingPlane //测量相关变量 this.actionType = ActionType.non; //鼠标动作 this.measurePoints = []; //测量数组 this.measureTempPoints = []; //测量面积数组 this.measurePolyline = undefined; //测量线 this.measurePolygon = undefined; //测量面 this.measureDistanceResult = 0; //测量长度 this.measureAreaResult = 0; //测量面积 //测量绘制点样式 this.measurePointStyle = { pixelSize: 8, color: this._toColor(0, 154, 94, 1.0), outlineColor: this._toColor(255, 255, 255, 1.0), outlineWidth: 1.0 }; //测量结果标注样式 this.measureLabelStyle = { font: '12px sans-serif', fillColor: this._toColor(255, 255, 255, 1.0), outlineColor: this._toColor(0, 154, 94, 1.0), style: Cesium.LabelStyle.FILL_AND_OUTLINE, outlineWidth: 1.0, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, pixelOffset: new Cesium.Cartesian2(0, -28), showBackground: true, backgroundColor: this._toColor(0, 0, 0, 0.6), }; //环绕飞行相关 this.angle = 0.1; //每次旋转的角度 值越大 旋转越快 this.flightListner = undefined; //环绕飞行监听函数 //区域旋转相关 this.areaRotation = Cesium.Math.toRadians(30); //案件标注图层文字及广告牌相关 this.caseLabels = undefined; this.caseLabelBillboards = undefined; //初始化地图 this._init3DMap(); //注册事件 this._eventRegister(); }, /** * 初始化三维地图 */ _init3DMap: function() { this.viewer = new Cesium.Viewer(this.selector, { animation: false, //是否显示动画控件 baseLayerPicker: false, //地图切换控件(底图以及地形图)是否显示,默认显示true timeline: false, //是否显示时间线控件,默认true navigationHelpButton: false, //是否显示帮助信息控件 sceneModePicker: false, //是否显示3D/2D选择器 infoBox: false, //点击要素之后显示的信息,默认true clampToGround: true, //开启贴地 homeButton: false, //主页按钮,默认true geocoder: false, //地名查找,默认true scene3DOnly: true, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源 fullscreenButton: false, //全屏按钮,默认显示true shadows: false, //阴影 // terrainExaggeration: 3.0, //地形夸大 // imageryProvider: new Cesium.TileMapServiceImageryProvider({ // url: 'https://a.tile.openstreetmap.org/' // }), imageryProvider: new Cesium.SingleTileImageryProvider({ url: Cesium.buildModuleUrl('Assets/Images/earth_3.jpg'), }), selectionIndicator: false, //选中元素显示,默认true选中元素显示,默认true }); this.viewer._cesiumWidget._creditContainer.style.display = "none"; //隐藏版本信息 /* 此项设置为true可以查看哪些内容掉到地下了 正常情况下设置为false 否则会导致绘制的点只能看见一半 */ this.viewer.scene.globe.depthTestAgainstTerrain = false; //地形不透明 地形检测 // this.viewer.imageryLayers.get(0).show = false; //删除默认加载的影像,显示蓝色地球 this.viewer.scene.skyBox.show = false; //是否显示星空 this.viewer.scene.sun.show = true; //是否显示太阳 this.viewer.scene.moon.show = false; //是否显示有月亮 this.viewer.scene.skyAtmosphere.show = true; //是否隐藏大气圈 this.viewer.scene.globe.show = true; //是否显示地球 this.viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType .LEFT_DOUBLE_CLICK); //取消鼠标左键双击 this.viewer.scene.debugShowFramesPerSecond = false; //是否显示帧FPS this.viewer.scene.requestRenderMode = true; //启动主动渲染 这样地图加载完成后停止渲染 可节省CPU的开支 //是否开启抗锯齿 this.viewer.scene.fxaa = true; this.viewer.scene.postProcessStages.fxaa.enabled = true; this.imageryLayers = this.viewer.imageryLayers; //赋值图层管理 this.primitives = this.viewer.scene.primitives; //原语集合 this.entities = this.viewer.entities; //实体集合 this.dataSources = this.viewer.dataSources; //数据源集合 /* 案件标注 */ this.caseLabels = this.viewer.scene.primitives.add(new Cesium.LabelCollection()); this.caseLabelBillboards = this.viewer.scene.primitives.add(new Cesium.BillboardCollection()); /* 开启精细渲染 不要太大 否则会导致效率下降 */ this.viewer._cesiumWidget._supportsImageRenderingPixelated = Cesium.FeatureDetection .supportsImageRenderingPixelated(); this.viewer._cesiumWidget._forceResize = true; if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) { var vtxf_dpr = window.devicePixelRatio; // 适度降低分辨率 while (vtxf_dpr >= 2.0) { vtxf_dpr /= 2.0; } // alert(vtxf_dpr); this.viewer.resolutionScale = 2.6; } }, /** * 注册事件 */ _eventRegister: function() { var self = this; //定义挂接画布的handler var handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas); /* 挂接鼠标移动动作 */ handler.setInputAction(function(moveEvent) { var pickMent = self.viewer.scene.pick(moveEvent.endPosition); var ray = self.viewer.camera.getPickRay(moveEvent.endPosition); var cartesian = self.viewer.scene.globe.pick(ray, self.viewer.scene); if (cartesian != undefined) { //世界坐标转地理坐标(弧度) var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian); //弧度转换为度 var point = [cartographic.longitude / Math.PI * 180, cartographic.latitude / Math .PI * 180 ]; //如果挂接了鼠标移动事件 则输出 if (self.onMouseMove != undefined) { self.onMouseMove(self._getCameraParameter()); } } /* Tooltip标签回调 */ if (Cesium.defined(pickMent)) { //鼠标移动到对象上 指的是Entity对象 如果注册了显示Toolstip的事件 则回调显示 //传递内容包括html ptx pty offsetx offsety isVisible if (self.onShowTooltip != undefined && pickMent.id && pickMent.id.tooltip) { self.onShowTooltip({ html: pickMent.id.tooltip.html, x: moveEvent.endPosition.x, y: moveEvent.endPosition.y, offsetx: pickMent.id.tooltip.anchor[0], offsety: pickMent.id.tooltip.anchor[1], visible: true, name: pickMent.id.name, height: self.viewer.camera.positionCartographic.height, }); } else { if (self.onShowTooltip != undefined) { self.onShowTooltip({ visible: false, name: undefined, }); } } } else { if (self.onShowTooltip != undefined) { self.onShowTooltip({ visible: false, name: undefined, }); } } /* BIM模型剪裁 */ if (Cesium.defined(self.planeSelected)) { // 计算鼠标移动的过程中产生的垂直高度距离 var deltaY = moveEvent.startPosition.y - moveEvent.endPosition.y; self.planeTargetY += deltaY; } // /* 测量长度 */ // if (self.actionType == ActionType.measureLength) { // self._eventMeasureLengthMouseMove(moveEvent) // } // /* 测量面积 */ // if (self.actionType == ActionType.measureArea) { // self._eventMeasureLengthMouseMove(moveEvent) // } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); /* 挂接鼠标点击动作 */ handler.setInputAction(function(event) { var pick = self.viewer.scene.pick(event.position); //查询动作 if (self.actionType == ActionType.queryAttribute) { if (self.onQueryStart != undefined) { self.onQueryStart(); } self.attributesEntity = []; //Entity查询 if (Cesium.defined(pick)) { //经过研究 统一一个出口 if (pick.id != undefined) { if (pick.id.description != undefined) { var config = JSON.parse(pick.id.name); self.attributesEntity.push({ layerName: config.name, attributes: JSON.parse(pick.id.description), geometry: config.geometry, }); } } } //ArcGIS矢量图层查询 self._queryVectorLayer(event.position); } else if (self.actionType == ActionType.measureLength) { self._eventMeasureLengthMouseClick(event); } else if (self.actionType == ActionType.measureArea) { self._eventMeasureAreaMouseClick(event); } else if (self.actionType == ActionType.flightAround) { if (self.flightListner != undefined) { self.viewer.clock.onTick.removeEventListener(self.flightListner); self.flightListner = undefined; self.actionType = ActionType.non; } else { self._startFlightAround(event); } } else if (self.actionType == ActionType.casePointQuery) { self._eventCasePointQueryMouseClick(event); } else if (self.actionType == ActionType.casePolygonQuery) { self._eventCasePolygonQueryMouseClick(event); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); /* 双指触摸变化事件 */ handler.setInputAction(function(moveEvent) { //如果挂接了鼠标移动事件 则输出 if (self.onMouseMove != undefined) { self.onMouseMove(self._getCameraParameter()); } }, Cesium.ScreenSpaceEventType.PINCH_MOVE); /* 右键点击事件 */ handler.setInputAction(function(event) { self._eventMeasureEnd(event); }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); /* 鼠标按下事件 */ handler.setInputAction(function(event) { var pick = self.viewer.scene.pick(event.position); if (Cesium.defined(pick) && Cesium.defined(pick.id) && Cesium.defined(pick.id.plane)) { self.planeSelected = pick.id.plane; self.planeSelected.material = Cesium.Color.BLUE.withAlpha(0.3); // 更改选中的切面颜色 self.planeSelected.outlineColor = Cesium.Color.WHITE; self.viewer.scene.screenSpaceCameraController.enableInputs = false; // 取消默认的鼠标一切输入事件 } }, Cesium.ScreenSpaceEventType.LEFT_DOWN); /* 鼠标松开事件 */ handler.setInputAction(function(event) { if (Cesium.defined(self.planeSelected)) { self.planeSelected.material = Cesium.Color.RED.withAlpha(0.1); // 恢复选中的切面颜色 self.planeSelected.outlineColor = Cesium.Color.WHITE; self.planeSelected = undefined; } self.viewer.scene.screenSpaceCameraController.enableInputs = true; // 恢复默认的鼠标一切输入事件 }, Cesium.ScreenSpaceEventType.LEFT_UP); /* 相机移动结束事件 */ self.viewer.camera.moveEnd.addEventListener(function(event) { //地图变化范围事件 if (self.onExtentChange != undefined) { //获取当前地图范围 var rect = self.viewer.camera.computeViewRectangle(); var result = { west: self._arcToDegree(rect.west), //西 south: self._arcToDegree(rect.south), east: self._arcToDegree(rect.east), //东 north: self._arcToDegree(rect.north), pitch: self._arcToDegree(self.viewer.camera.pitch), heading: self._arcToDegree(self.viewer.camera.heading), height: self.viewer.camera.positionCartographic.height, } self.onExtentChange(result); }; //如果挂接了鼠标移动事件 则输出 if (self.onMouseMove != undefined) { self.onMouseMove(self._getCameraParameter()); } }); //渲染新帧后的更新/渲染周期结束时, self.viewer.scene.postRender.addEventListener(function() { if (self.onPostSceneChange != undefined) { self.resetLabelLocation(); /* 需要传递一些参数出去 */ self.onPostSceneChange({ pitch: self._arcToDegree(self.viewer.camera.pitch), heading: self._arcToDegree(self.viewer.camera.heading), height: self.viewer.camera.positionCartographic.height, }); } }); }, /** * 查询ArcGIS服务图层的地图范围 * @param {string} url 服务地址 * @param {int} index 图层索引 * @param {JSON} callSuccess 成功回调{xmin:ymin:xmax:ymax:} * @param {string} callError 失败回调(errorString) */ _queryAGServerExtent: function(url, index, callSuccess, callError) { $.ajax({ async: true, type: 'POST', dataType: 'json', url: url + '/' + index + '?f=pjson', success: function(data) { if (callSuccess != undefined) { callSuccess({ xmin: data.extent.xmin, ymin: data.extent.ymin, xmax: data.extent.xmax, ymax: data.extent.ymax, }); } }, error: function(XMLHttpRequest, textStatus, errorThrown) { //通常情况下textStatus和errorThrown只有其中一个包含信息 if (callError != undefined) { callError(textStatus); } } }); }, /** * 查询ArcGIS服务图层的数据 * @param {JSON} options * where{string}:查询条件 * geometry{JSONString}:查询关联的要素 JSON字符串 * fields{string}:需要查询的字段 逗号分隔开的字符串 * returnGeometry{boolean}[true/false]:是否返回要素 * @param {JSON} callSuccess 成功回调 返回的JSON数组 * @param {String} callError 失败回调(errorString) */ _queryArcGISGeoJSON: function(options, callSuccess, callError) { var queryParam = {} //查询文字条件 if (options.where == undefined) { queryParam.where = "1=1"; } else { queryParam.where = "1=1 and " + options.where; } queryParam.text = ""; queryParam.objectIds = ""; queryParam.time = ""; //查询区域 if (options.geometry == undefined) { queryParam.geometry = ""; } else { queryParam.geometry = options.geometry; } /* 设置输入的查询区域类型 */ queryParam.geometryType = options.geometryType == undefined ? "esriGeometryEnvelope" : options .geometryType; queryParam.inSR = ""; queryParam.spatialRel = "esriSpatialRelIntersects"; queryParam.relationParam = ""; //查询字段集合 if (options.fields == undefined) { queryParam.outFields = "*"; } else { queryParam.outFields = options.fields; } if (options.returnGeometry == undefined) { queryParam.returnGeometry = false; } else { queryParam.returnGeometry = options.returnGeometry; } queryParam .maxAllowableOffset = ""; queryParam.geometryPrecision = ""; queryParam.outSR = ""; queryParam.returnIdsOnly = false; queryParam.returnCountOnly = false; queryParam.orderByFields = ""; queryParam.groupByFieldsForStatistics = ""; queryParam.outStatistics = ""; queryParam.returnZ = ""; queryParam.returnM = ""; queryParam.gdbVersion = ""; queryParam.returnDistinctValues = ""; queryParam.f = "pjson"; /* 打印一下参数看看 */ // console.log("服务要素查询参数 = " + JSON.stringify(queryParam)); //开始查询 $.ajax({ async: true, type: 'POST', dataType: 'jsonp', contentType: 'application/x-www-form-urlencoded; charset=UTF-8', url: options.url + '/query', data: queryParam, success: function(data) { if (data.error != undefined) { if (callError != undefined) callError(data.error.message); } if (callSuccess != undefined) callSuccess(data); }, error: function(XMLHttpRequest, textStatus, errorThrown) { if (callError != undefined) callError(errorThrown); } }); }, /** * 检测当前的索引是否查过图层总数 * @param {int} index 索引 */ _checkLayerIndex: function(index) { if (this.imageryLayers == undefined || index == undefined) return false; var layerIndex = parseFloat(index); if (layerIndex < this.imageryLayers.length) return true; else return false; }, /** * @param {int} layerIndex 当前图层索引 * @param {string} layerIndex */ _consoleLayerInfo: function(layerIndex, layerId) { return; console.log("已有图层数量:" + this.imageryLayers.length + " 当前图层索引:" + layerIndex); var result = this._searchCorrelationLayerIndex(layerId); if (result == undefined) { console.log("图层Id=" + layerId + " 上下均未有关联图层!"); } else { console.log("图层Id=" + layerId + " 底部图层索引=" + result.minIndex + " 顶部图层索引=" + result.maxIndex); } }, /** * 搜索指定Id的上下关联图层索引 * @param {string} layerId 图层Id */ _searchCorrelationLayerIndex: function(layerId) { var index = this.beforeLayerIds.indexOf(layerId); if (index == -1) return undefined; var minIndex = -1; var maxIndex = -1; /* 找该图层底部的图层 */ for (var i = index - 1; i >= 0; i--) { minIndex = this.imageryLayers.indexOf(window[this.beforeLayerIds[i]]); if (minIndex != -1) { break; } } /* 找该图层顶部的图层 */ for (var i = index + 1; i < this.beforeLayerIds.length; i++) { maxIndex = this.imageryLayers.indexOf(window[this.beforeLayerIds[i]]); if (maxIndex != -1) { break; } } /* 返回寻找结果 */ return { minIndex: minIndex, maxIndex: maxIndex }; }, /** * 添加provider到地图中 * @param {Object} provider 图层构建器 * @param {Object} layerId 图层Id */ _addImageryProvider: function(provider, layerId) { var resSearch = this._searchCorrelationLayerIndex(layerId); var resLayer = undefined; if (resSearch != undefined && resSearch.maxIndex != -1) { /* 找到该图层顶部的关联图层 则直接插入到该图层到底部 */ resLayer = this.imageryLayers.addImageryProvider(provider, resSearch.maxIndex); } else if (resSearch != undefined && resSearch.minIndex != -1 && resSearch.minIndex != this .imageryLayers.length - 1) { /* 找到该图层底部关联的图层 且该图层不是最顶部的图层 则将该图层加载到这个图层之上 */ resLayer = this.imageryLayers.addImageryProvider(provider, resSearch.minIndex + 1); } else { resLayer = this.imageryLayers.addImageryProvider(provider); } return resLayer; }, /** * @param {int} red 红色[0~255] * @param {int} green 绿色[0~255] * @param {int} blue 蓝色[0~255] * @param {int} alpha 透明度[0~1] */ _toColor: function(red, green, blue, alpha) { return new Cesium.Color(red / 255.0, green / 255.0, blue / 255.0, alpha) }, /** * 弧度转度 * @param {float} arc 弧度 */ _arcToDegree: function(arc) { return arc / Math.PI * 180; }, /** * 获取海拔高度等信息 * @param {Object} screenPoint 屏幕点 */ _getHeightPoint: function(screenPoint) { var self = this; var viewer = this.viewer; var pick = new Cesium.Cartesian2(screenPoint.x, screenPoint.y); let resultPoint = {}; if (pick) { //根据射线和场景求出在球面中的笛卡尔坐标 var cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(pick), viewer.scene); //获取该浏览器坐标的顶部数据 var feature = viewer.scene.pick(screenPoint); if (cartesian) { //世界坐标转地理坐标(弧度) var cartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian); if (cartographic) { //海拔 var height = viewer.scene.globe.getHeight(cartographic); //视角海拔高度 var he = Math.sqrt(viewer.scene.camera.positionWC.x * viewer.scene.camera.positionWC.x + viewer.scene.camera.positionWC.y * viewer.scene.camera.positionWC.y + viewer .scene.camera.positionWC.z * viewer.scene.camera.positionWC.z); var he2 = Math.sqrt(cartesian.x * cartesian.x + cartesian.y * cartesian.y + cartesian .z * cartesian.z); //地理坐标(弧度)转经纬度坐标 var point = [cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180 ]; if (!height) { height = 0; } if (!he) { he = 0; } if (!he2) { he2 = 0; } if (!point) { point = [0, 0]; } resultPoint['x'] = point[0].toFixed(6); //经度 resultPoint['y'] = point[0].toFixed(6); //纬度 resultPoint['z'] = height.toFixed(1); //海拔 resultPoint['m'] = (he - he2).toFixed(1); //视角(相机)高度 resultPoint['h'] = height.toFixed(1); //建筑物海拔高度 } } if (feature != undefined) { let cartesian = viewer.scene.pickPosition(screenPoint); if (Cesium.defined(cartesian)) { //如果对象已定义,将度转为经纬度 let cartographic = Cesium.Cartographic.fromCartesian(cartesian); let lon = Cesium.Math.toDegrees(cartographic.longitude); let lat = Cesium.Math.toDegrees(cartographic.latitude); let MouseHeight = cartographic.height; //模型高度 resultPoint['h'] = MouseHeight.toFixed(1); } } } return resultPoint; }, /** * 三维模型旋转平移 * @param {Object} tileset 三维模型数据 * @param {JSON} params * params参数{tx:{float}x方向平移 ty:{float}y方向平移 tz:{float}z方向平移} * params参数{rx:{float}x方向旋转 ry:{float}y方向旋转 rz:{float}z方向旋转} */ _update3dtilesMaxtrix: function(tileset, params) { //旋转 var mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(params.rx)); var my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(params.ry)); var mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(params.rz)); var rotationX = Cesium.Matrix4.fromRotationTranslation(mx); var rotationY = Cesium.Matrix4.fromRotationTranslation(my); var rotationZ = Cesium.Matrix4.fromRotationTranslation(mz); //平移 var position = Cesium.Cartesian3.fromDegrees(params.tx, params.ty, params.tz); var m = Cesium.Transforms.eastNorthUpToFixedFrame(position); //旋转、平移矩阵相乘 Cesium.Matrix4.multiply(m, rotationX, m); Cesium.Matrix4.multiply(m, rotationY, m); Cesium.Matrix4.multiply(m, rotationZ, m); //赋值给tileset tileset._root.transform = m; }, /** * 世界坐标系坐标转换为经纬度坐标 * @param {Object} coord 世界坐标系坐标 */ _wordToWGS84: function(coord) { var g84 = Cesium.Ellipsoid.WGS84.cartesianToCartographic(coord); var lat = Cesium.Math.toDegrees(g84.latitude); var lng = Cesium.Math.toDegrees(g84.longitude); var alt = g84.height; return { lng: lng, lat: lat, alt: alt, } }, _getDataUri: function(url, callback) { var image = new Image(); image.onload = function() { var canvas = document.createElement('canvas'); canvas.width = this.naturalWidth; // or 'width' if you want a special/scaled size canvas.height = this.naturalHeight; // or 'height' if you want a special/scaled size canvas.getContext('2d').drawImage(this, 0, 0); // Get raw image data callback(canvas.toDataURL('image/png').replace(/^data:image\/(png|jpg);base64,/, '')); // ... or get as Data URI callback(canvas.toDataURL('image/png')); }; image.src = url; }, /** * 获取相机输出参数 */ _getCameraParameter: function() { var self = this; var position = this._getCameraPosition(); return { screenX: '', screenY: '', mapX: position.lng.toFixed(6), mapY: position.lat.toFixed(6), mapZ: position.alt.toFixed(2), pitch: self._arcToDegree(self.viewer.camera.pitch), height: self.viewer.camera.positionCartographic.height, heading: self._arcToDegree(self.viewer.camera.heading), } }, /** * 获取相机位置{lng: lat: alt:} */ _getCameraPosition: function() { var ellipsoid = this.viewer.scene.globe.ellipsoid; var position = this.viewer.camera.position; var cartographic = ellipsoid.cartesianToCartographic(position); return { lng: this._arcToDegree(cartographic.longitude), lat: this._arcToDegree(cartographic.latitude), alt: cartographic.height, } }, /** * 获取屏幕点的经纬度及高度 如果点击位置有模型则获取模型高度 否则获取地形高度 * @param {JSON} screenPoint 屏幕点 * x{float}:x位置 * y{float}:y位置 */ _getLocation: function(screenPoint) { var lng = undefined, lat = undefined, height = undefined; /* 从相机位置到 windowPosition 处的像素创建射线在世界坐标系中 */ var ray = this.viewer.scene.camera.getPickRay(screenPoint); /* 找到射线与渲染的地球表面之间的交点 */ var position = this.viewer.scene.globe.pick(ray, this.viewer.scene); /* 获取地理位置的制图表达 */ var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position); /* 查询屏幕位置的要素 */ var feature = this.viewer.scene.pick(screenPoint); if (feature == undefined) { lng = Cesium.Math.toDegrees(cartographic.longitude); lat = Cesium.Math.toDegrees(cartographic.latitude); height = cartographic.height; console.log("地形高度 = " + height); } else { var cartesian = this.viewer.scene.pickPosition(screenPoint); if (Cesium.defined(cartesian)) { var cartographic = Cesium.Cartographic.fromCartesian(cartesian); lng = Cesium.Math.toDegrees(cartographic.longitude); lat = Cesium.Math.toDegrees(cartographic.latitude); height = cartographic.height; console.log("三维高度 = " + height); } } /* 返回结果 */ return { lng: lng, lat: lat, height: height, } } }) /** * 图层相关 */ CrMap.prototype.extend({ /** * 设置地形 * @param {JSON} options * url{string}:地形服务URL地址 */ setTerrainLayer: function(options) { var terrainLayer = new Cesium.CesiumTerrainProvider({ url: options.url, // 默认立体地表 // 请求照明 requestVertexNormals: true, // 请求水波纹效果 requestWaterMask: true }); this.viewer.terrainProvider = terrainLayer; /* 保存值公共变量 后期使用 */ window['dem'] = terrainLayer; }, /** * 添加Mapbox图层 * @param {JSON} options * id{String}:图层Id * isshow{boolean}[true/false]:是否显示 */ addMapboxLayer: function(options) { this._consoleLayerInfo(options.index, options.id); var mapboxProvider = new Cesium.MapboxStyleImageryProvider({ url: 'https://api.mapbox.com/styles/v1', username: 'chenchen1990', styleId: 'ckvgc14xrh7mo14qowdw4wrkf', accessToken: 'pk.eyJ1IjoiY2hlbmNoZW4xOTkwIiwiYSI6ImNrbzA3eTY1OTA3dXkyd20zdG40ZGdmNXYifQ.xWKxjBG6mEDh55_oln0nAg', scaleFactor: true }); /* 加入图层 */ var mapboxLayer = this._addImageryProvider(mapboxProvider, options.id); /* 控制是否显示 */ mapboxLayer.show = options.isshow == undefined ? true : options.isshow; /* 加入到整体图层中 以便可以删除对应的图层 */ window[options.id] = mapboxLayer; }, /** * 添加在线影像地图 * @param {JSON} options * id{string}:图层id * isshow{boolean}[true/false]:是否显示 */ addOnlineRasterLayer: function(options) { this._consoleLayerInfo(options.index, options.id); /* 加载影像图底图 */ var tdtImageURL = "https://{s}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=2471a323eac0646da7c7af7e16788b71"; var tdtImageURLTemplate = new Cesium.UrlTemplateImageryProvider({ url: tdtImageURL, tilingScheme: new Cesium.WebMercatorTilingScheme(), minimumLevel: 0, maximumLevel: 18, subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"], }); var layerRaseter = this._addImageryProvider(tdtImageURLTemplate, options.id); layerRaseter.gamma = 0.5; layerRaseter.show = options.isshow == undefined ? true : options.isshow; /* 加载影像图标签 */ var tdtImageLabelURL = "https://{s}.tianditu.gov.cn/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=2471a323eac0646da7c7af7e16788b71"; var tdtImageLabelURLTemplate = new Cesium.UrlTemplateImageryProvider({ url: tdtImageLabelURL, tilingScheme: new Cesium.WebMercatorTilingScheme(), minimumLevel: 0, maximumLevel: 18, subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"], }); /* 标注添加到最顶层 */ var layerLabel = this.imageryLayers.addImageryProvider(tdtImageLabelURLTemplate);; layerLabel.show = options.isshow == undefined ? true : options.isshow; //查询标注图层索引 然后在其下方加载对应的图层 var labelIndex = this.imageryLayers.indexOf(layerLabel); /* 加入到整体图层中 以便可以删除对应的图层 */ window[options.id] = layerRaseter; window[options.id + labelFlag] = layerLabel; }, /** * 添加在线标准地图 * @param {JSON} options * id{string}:图层id * isshow{boolean}[true/false]:是否显示 */ addOnlineVectorLayer: function(options) { this._consoleLayerInfo(options.index, options.id); /* 加载矢量底图 */ var tdtImageURL = "https://{s}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=2471a323eac0646da7c7af7e16788b71"; var tdtImageURLTemplate = new Cesium.UrlTemplateImageryProvider({ url: tdtImageURL, tilingScheme: new Cesium.WebMercatorTilingScheme(), minimumLevel: 0, maximumLevel: 18, subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"], }); var layerVector = this._addImageryProvider(tdtImageURLTemplate, options.id); layerVector.gamma = 0.1; layerVector.show = options.isshow == undefined ? true : options.isshow; //首先添加标注图层 var tdtImageLabelURL = "https://{s}.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=2471a323eac0646da7c7af7e16788b71"; var tdtImageLabelURLTemplate = new Cesium.UrlTemplateImageryProvider({ url: tdtImageLabelURL, tilingScheme: new Cesium.WebMercatorTilingScheme(), minimumLevel: 0, maximumLevel: 18, subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"], }); var layerLabel = this.imageryLayers.addImageryProvider(tdtImageLabelURLTemplate); layerLabel.gamma = 0.2; layerLabel.show = options.isshow == undefined ? true : options.isshow; /* 加入到整体图层中 以便可以删除对应的图层 */ window[options.id] = layerVector; window[options.id + labelFlag] = layerLabel; }, /** * @param {JSON} options * url{string}:wmts服务地址 * maxLevel{int}:最大缩放层级 * minLevel{int}:最小缩放层级 * isshow{boolean}[true/false]:是否显示 * alpha{float}[0.0-1.0]:透明度 */ addWmtsTileLayer: function(options) { this._consoleLayerInfo(options.index, options.id); var wmtsProvider = new Cesium.WebMapTileServiceImageryProvider({ url: options.url, layer: 1, style: 'default', format: 'image/png', tileMatrixSetID: 'default028mm', maximumLevel: options.maxLevel, minimumLevel: options.minLevel, }); var wmtslayer = this._addImageryProvider(wmtsProvider, options.id); wmtslayer.show = options.isshow == undefined ? true : options.isshow; /*加入到窗体中*/ window[options.id] = wmtslayer; window[options.id].alpha = options.alpha == undefined ? 1.0 : parseFloat(options.alpha); }, /** * 加载ArcGIS矢量图层 * @param {JSON} options 参数集合 * id{string}:图层Id 唯一标识 * url{string}:服务地址 * layers{array}:图层数组 [0] * isshow{boolean}[true/false]:是否显示 * isQuery{boolean}[true/false]:是否支持查询 * label{JSON}:标注配置 * url{string}:标注地址 * lng{string}:标注位置的经度字段名称 * lat{string}:标注位置的纬度字段名称 * alt{string}:标注位置的高度字段名称 * key{string}:标注显示内容的字段名称 * size{int}:标注的大小 单位是px 无需带px * family{string}:标注的字体名称 * color{string}:标注的颜色,为使用逗号分隔开的字符串 233,124,234 * display{int}:标注的显示距离 * image{string}:标注关联的广告牌路径 */ addAGSVectorServer: function(options) { this._consoleLayerInfo(options.index, options.id); var self = this; self._queryAGServerExtent(options.url, options.layers[0], function(data) { var gisProvider = new Cesium.ArcGisMapServerImageryProvider({ url: options.url, layers: options.layers, rectangle: Cesium.Rectangle.fromDegrees(data.xmin, data.ymin, data.xmax, data.ymax), }); //添加到图层中 var layer = self._addImageryProvider(gisProvider, options.id); layer.show = options.isshow == undefined ? true : options.isshow; //控制是否显示 //判断是否需要加入到查询数组 if (options.isQuery != undefined && options.isQuery) { //判断是否已经存在 var isExists = false; for (var qIdx = 0; qIdx < self.queryLayers.length; qIdx++) { if (self.queryLayers[qIdx].id == options.id) { isExists = true; break; } } if (!isExists) { self.queryLayers.push({ id: options.id, provider: gisProvider, }); } } if (options.label != undefined) { var queryFields = options.label.lat + "," + options.label.lng + "," + options .label .alt + "," + options.label.key; //追加属性 如果是多图片显示 if (options.label.images != undefined) { queryFields += "," + options.label.images.key; } //如果存在移动弹出信息 则对查询字段进行组合 var entityTooltip = options.label.tooltip; if (entityTooltip != undefined) { queryFields += "," + entityTooltip.key + "," + entityTooltip.fields.join(); } self._queryArcGISGeoJSON({ url: options.label.url, fields: queryFields, }, function(resData) { var parentEntity = self.viewer.entities.add(new Cesium.Entity({ name: options.id, })); parentEntity.show = options.isshow == undefined ? true : options .isshow; //设置是否显示 //查询结束 开始添加标注 for (var i = 0; i < resData.features.length; i++) { var lng = resData.features[i].attributes[options.label.lng]; var lat = resData.features[i].attributes[options.label.lat]; var alt = resData.features[i].attributes[options.label.alt]; var key = resData.features[i].attributes[options.label.key]; var entity = self.viewer.entities.add({ name: options.id, parent: parentEntity, position: Cesium.Cartesian3.fromDegrees(lng, lat, parseFloat(alt) + 50), label: { text: key, font: options.label.size + 'px ' + options.label .family, scale: 0.5, fillColor: Cesium.Color.WHITE, outlineColor: Cesium.Color.fromCssColorString( 'rgba(' + options.label.color + ')'), outlineWidth: 4, style: Cesium.LabelStyle.FILL_AND_OUTLINE, horizontalOrigin: Cesium.HorizontalOrigin.LEFT, verticalOrigin: Cesium.VerticalOrigin.center, pixelOffset: new Cesium.Cartesian2(20, 0), showBackground: false, backgroundColor: new Cesium.Color(0.5, 0.6, 1, 0.5), distanceDisplayCondition: new Cesium .DistanceDisplayCondition(0, options.label .display), }, billboard: { image: self.serverUrl + options.label.image, horizontalOrigin: Cesium.HorizontalOrigin .center, verticalOrigin: Cesium.VerticalOrigin.center, scale: 0.5, } }); //如果是多图片显示 则重置entity的广告牌图片 if (options.label.images != undefined) { var value = resData.features[i].attributes[options.label .images .key]; var config = options.label.images.config; for (var idx = 0; idx < config.length; idx++) { var minValue = config[idx].minValue; var maxValue = config[idx].maxValue; if (value >= minValue && value <= maxValue) { entity.billboard.image = config[idx].icon; break; } } } //加入实体 //组合弹出信息 if (entityTooltip != undefined) { var htmlJSON = {}; htmlJSON['key'] = resData.features[i].attributes[ entityTooltip .key]; for (var fld = 0; fld < entityTooltip.fields .length; fld++) { htmlJSON[entityTooltip.fields[fld]] = resData.features[ i] .attributes[entityTooltip.fields[fld]]; } entity.tooltip = { html: JSON.stringify(htmlJSON), anchor: [0, 30], } } } window[options.id] = layer; window[options.id + labelFlag] = parentEntity; }); } else { window[options.id] = layer; } }, function(err) { }); }, /** * 加载ArcGIS矢量图层 * @param {JSON} options 参数集合 * id{string}:图层Id 唯一标识 * url{string}:服务地址 * layers{array}:图层数组 [0] * isshow{boolean}[true/false]:是否显示 * isQuery{boolean}[true/false]:是否支持查询 * label{JSON}:标注配置 * url{string}:标注地址 * lng{string}:标注位置的经度字段名称 * lat{string}:标注位置的纬度字段名称 * alt{string}:标注位置的高度字段名称 * key{string}:标注显示内容的字段名称 * size{int}:标注的大小 单位是px 无需带px * family{string}:标注的字体名称 * color{string}:标注的颜色,为使用逗号分隔开的字符串 233,124,234 * display{int}:标注的显示距离 * offset{array}:标注的偏移距离[0,0] * scale{float}:标注的显示比例 * billboard{JSON}:广告牌配置 * image{string}:关联的广告牌路径 * display{int}:广告牌的显示距离 * offset{array}:广告牌的偏移距离[0,0] * scale{float}:广告牌的显示比例 */ addAGSVectorServerToo: function(options) { this._consoleLayerInfo(options.index, options.id); var self = this; self._queryAGServerExtent(options.url, options.layers[0], function(data) { var gisProvider = new Cesium.ArcGisMapServerImageryProvider({ url: options.url, layers: options.layers, rectangle: Cesium.Rectangle.fromDegrees(data.xmin, data.ymin, data.xmax, data.ymax), }); //添加到图层中 var layer = self._addImageryProvider(gisProvider, options.id); layer.show = options.isshow == undefined ? true : options.isshow; //控制是否显示 //判断是否需要加入到查询数组 if (options.isQuery != undefined && options.isQuery) { //判断是否已经存在 var isExists = false; for (var qIdx = 0; qIdx < self.queryLayers.length; qIdx++) { if (self.queryLayers[qIdx].id == options.id) { isExists = true; break; } } if (!isExists) { self.queryLayers.push({ id: options.id, provider: gisProvider, }); } } if (options.label != undefined) { var queryFields = options.label.lat + "," + options.label.lng + "," + options .label .alt + "," + options.label.key; //如果存在移动弹出信息 则对查询字段进行组合 var entityTooltip = options.label.tooltip; if (entityTooltip != undefined) { queryFields += "," + entityTooltip.key + "," + entityTooltip.fields.join(); } self._queryArcGISGeoJSON({ url: options.label.url, fields: queryFields, }, function(resData) { var parentEntity = self.viewer.entities.add(new Cesium.Entity({ name: options.id, })); parentEntity.show = options.isshow == undefined ? true : options .isshow; //设置是否显示 //查询结束 开始添加标注 for (var i = 0; i < resData.features.length; i++) { var lng = resData.features[i].attributes[options.label.lng]; var lat = resData.features[i].attributes[options.label.lat]; var alt = resData.features[i].attributes[options.label.alt]; var key = resData.features[i].attributes[options.label.key]; var entity = self.viewer.entities.add({ name: options.id, parent: parentEntity, position: Cesium.Cartesian3.fromDegrees(lng, lat, parseFloat(alt) - 0), label: { text: key, font: options.label.size + 'px ' + options.label .family, scale: options.label.scale, fillColor: Cesium.Color.fromCssColorString( 'rgba(' + options.label.color + ')'), horizontalOrigin: Cesium.HorizontalOrigin .CENTER, verticalOrigin: Cesium.VerticalOrigin.CENTER, pixelOffset: new Cesium.Cartesian2(options.label .offset[0], options.label.offset[1]), distanceDisplayCondition: new Cesium .DistanceDisplayCondition(0, options.label .display), eyeOffset: new Cesium.Cartesian3(0, 0, -10) } }); if (options.billboard != undefined) { entity.billboard = { image: options.billboard.image, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, scale: options.billboard.scale, verticalOrigin: Cesium.VerticalOrigin.BASELINE, pixelOffset: new Cesium.Cartesian2(options.billboard .offset[0], options.billboard.offset[1]), distanceDisplayCondition: new Cesium .DistanceDisplayCondition(0, options.billboard .display), } } //组合弹出信息 if (entityTooltip != undefined) { var htmlJSON = {}; htmlJSON['key'] = resData.features[i].attributes[ entityTooltip .key]; for (var fld = 0; fld < entityTooltip.fields .length; fld++) { htmlJSON[entityTooltip.fields[fld]] = resData.features[ i] .attributes[entityTooltip.fields[fld]]; } entity.tooltip = { html: JSON.stringify(htmlJSON), anchor: [0, 30], } } } window[options.id] = layer; window[options.id + labelFlag] = parentEntity; }); } else { window[options.id] = layer; } }, function(err) { }); }, /** * @param {JSON} options * url[{string}]:资源的Url数组 * id{string}:图层Id * isshow{boolean}[true/false]:是否显示 * params参数{tx:{float}x方向平移 ty:{float}y方向平移 tz:{float}z方向平移} * params参数{rx:{float}x方向旋转 ry:{float}y方向旋转 rz:{float}z方向旋转} */ add3DTilesets: function(options) { var self = this; var subLayerIds = []; var tilesets = new Cesium.PrimitiveCollection(); for (var i = 0; i < options.url.length; i++) { var url = options.url[i]; var tileLayer = new Cesium.Cesium3DTileset({ url: url, show: options.isshow == undefined ? true : options.isshow, maximumScreenSpaceError: 16, maxmumMemoryUsage: 218, skipScreenSpaceErrorFactor: 16, dynamicScreenSpaceError: true, skipLevels: 1, cullWithChildrenBounds: true, cullRequestsWhileMoving: true, cullRequestsWhileMovingMultiplier: 10, // 值越小能够更快的剔除 }); var tileset = tilesets.add(tileLayer); tileset.readyPromise.then(function(primitive) { if (options.params != undefined) { self._update3dtilesMaxtrix(primitive, options.params); } }) } /* 加入图层 */ this.primitives.add(tilesets); /* 加入公共资源 */ window[options.id] = tilesets; }, /** * @param {JSON} options * id{string}:图层Id * isshow{boolean}[true/false]:是否显示 * model{JSON数组}[{url:glb地址,lng:lat:alt:},{}] 加载的glb文件JSON格式数组 */ addGlbs: function(options) { /* 如果没有配置模型则返回 */ if (options.model == undefined || options.model.length == 0) rturn; var self = this; var layer = undefined; /* 创建第0个glb 作为飞行点 */ var model0 = options.model[0]; var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame( Cesium.Cartesian3.fromDegrees(model0.lng, model0.lat, model0.alt) ); var parentEntity = self.entities.add({ name: options.id, position: Cesium.Cartesian3.fromDegrees(model0.lng, model0.lat, model0.alt), model: { uri: model0.name, modelMatrix: modelMatrix, scale: 1.0 //放大倍数 }, }); /* 设置显示或隐藏 */ parentEntity.show = options.isshow == undefined ? true : options.isshow; /* 挂接其他大棚 */ for (var i = 1; i < options.model.length; i++) { var model = options.model[i]; var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame( Cesium.Cartesian3.fromDegrees(model.lng, model.lat, model.alt) ); //做个实验试试 var entity = self.entities.add({ parent: parentEntity, name: options.id, position: Cesium.Cartesian3.fromDegrees(model.lng, model.lat, model.alt), model: { uri: model.name, modelMatrix: modelMatrix, scale: 1.0 //放大倍数 }, }); } /* 加入到全局*/ window[options.id] = parentEntity; }, /** * 添加GeoJSON数据图层 * @param {JSON} options 配置项 * url{String}:数据地址 * line{JSON}:线的配置 * line.width{int}宽度 * line.power{double}[0-1]:发光强度 * line.color{} */ addGeoJSONLayer: function(options) { var self = this; /* 加载JSON数据 */ var promise = Cesium.GeoJsonDataSource.load(options.url, { clampToGround: true, }); promise.then(function(dataSource) { /* 设置数据源的名称 */ dataSource.name = options.id; /* 添加数据源 */ self.dataSources.add(dataSource); var entities = dataSource.entities.values; var lineWidth = 20; var linePower = 0.2; var lineColor = Cesium.Color.ORANGERED.withAlpha(.9); /* 根据配置项判断是否进行了相关设置 */ if (options.line != undefined) { if (options.line.width != undefined) lineWidth = options.line.width; if (options.line.power != undefined) linePower = options.line.power; if (options.line.color != undefined) { var jsonColor = options.line.color; if (jsonColor.r != undefined && jsonColor.g != undefined && jsonColor.b != undefined && jsonColor.a != undefined) { lineColor = self._toColor(jsonColor.r, jsonColor.g, jsonColor.b, jsonColor .a); } } } for (var o = 0; o < entities.length; o++) { var entity = entities[o]; entity.nameID = o; //给每条线添加一个编号,方便之后对线修改样式 entity.polyline.width = lineWidth; //添加默认样式 (entity.polyline.material = new Cesium.PolylineGlowMaterialProperty({ glowPower: linePower, //一个数字属性,指定发光强度,占总线宽的百分比。 color: lineColor, }), 10) } /* 加入到全局 */ window[options.id] = dataSource; }) }, /** * 从服务中根据范围查询要素并添加到地图图层中 * @param {JSON} options * geometry{String}:坐标字符串,使用逗号分隔 * fields{String}:输出字段,如果输出全部,可不输出,字段之间使用逗号分隔 * @param {Function(JSON)} callSuccess 成功回调 * @param {Function(String)} callError 失败回调 */ addFeaturesFromServerByPolygon: function(options,callSuccess,callError) { this._queryArcGISGeoJSON({ geometry: options.geometry, geometryType: options.geometryType == 'polygon'?'esriGeometryPolygon':'esriGeometryEnvelope', fields: options.fields == undefined ? "*" : options.fields, returnGeometry: true, url: options.url }, function(resData) { if(callSuccess != undefined) callSuccess(resData); }, function(err) { if(callError != undefined) callError(err); }); }, /** * 删除加载的所有图层 */ removeAllLayer: function() { this.imageryLayers.removeAll(); this.viewer.entities.removeAll(); this.viewer.scene.primitives.removeAll(); this.queryLayers = []; this.dataSources.removeAll(); }, /** * 移除图层 * @param {Object} layerId 图层Id */ removeLayer: function(layerId) { this.imageryLayers.remove(window[layerId]); this.primitives.remove(window[layerId]); this.dataSources.remove(window[layerId]); /* 如果标注层存在则同步删除 */ if (window[layerId + labelFlag] != undefined) { this.imageryLayers.remove(window[layerId + labelFlag]); var entities = this.viewer.entities; var delEntitys = []; //循环查找符合条件的Entity for (var i = 0; i < entities.values.length; i++) { if (entities.values[i].name == layerId) { delEntitys.push(entities.values[i]); } } //删除符合条件的Entity for (var i = 0; i < delEntitys.length; i++) { entities.remove(delEntitys[i]); } } /* 如果该图层是Entity 则根据名称判断是否需要删除 */ if (window[layerId] instanceof Cesium.Entity) { var entities = this.viewer.entities; var delEntitys = []; //循环查找符合条件的Entity for (var i = 0; i < entities.values.length; i++) { if (entities.values[i].name == layerId) { delEntitys.push(entities.values[i]); } } //删除符合条件的Entity for (var i = 0; i < delEntitys.length; i++) { entities.remove(delEntitys[i]); } } /* 如果图层可查询 则移除 */ for (var i = 0; i < this.queryLayers.length; i++) { var qConfig = this.queryLayers[i]; if (qConfig.id == layerId) { this.queryLayers.splice(i, 1); } } }, }) /** * 图斑标注相关 */ CrMap.prototype.extend({ /** * @param {JSON} options 配置项 */ addCaseLabel: function(options) { var self = this; var longitude = parseFloat(options.lng); var latitude = parseFloat(options.lat); var altitude = parseFloat(options.alt); this.caseLabels.add({ position: new Cesium.Cartesian3.fromDegrees(longitude, latitude, altitude), text: options.text, font: '22px SansCN-Normal', fillColor: Cesium.Color.WHITE, outlineColor: self._toColor(11, 48, 115, 1.0), outlineWidth: 2, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, style: Cesium.LabelStyle.FILL_AND_OUTLINE, verticalOrigin: Cesium.VerticalOrigin.CENTER, distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000), heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, eyeOffset: new Cesium.Cartesian3(0, 0, -10), pixelOffset: new Cesium.Cartesian2(10, -50), scale: 0.45 }); this.caseLabelBillboards.add({ position: new Cesium.Cartesian3.fromDegrees(longitude, latitude, altitude), image: self.serverUrl + options.image, distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000), heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, scale: 0.5, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.BASELINE, }); /* 刷祯 */ this.updateSence(); }, /** * 删除全部图斑标注 */ removeAllCaseLabel: function() { var self = this; return new Promise((resolve, reject) => { self.caseLabels.removeAll(); self.caseLabelBillboards.removeAll(); resolve(true); }); }, /** * 添加当前可视区域 * @param {JSON} options 配置项 * strLng{double}:矩形起始点经度 * strLat{double}:矩形起始点纬度 * endLng{double}:矩形终止点经度 * endLat{double}:矩形终止点纬度 */ addAreaRectangle: function(options) { var self = this; this.entities.removeById('areaRectangle'); var extent = Cesium.Rectangle.fromDegrees(options.strLng, options.strLat, options.endLng, options .endLat); var flyRectangle = this.entities.add({ id: 'areaRectangle', name: 'areaRectangle', rectangle: { coordinates: extent, material: Cesium.Color.GREEN.withAlpha(0.6), height: 10.0, outline: false } }); }, /** * 计算高程 * @param {JSON} options 配置项 * points{Array[JSON(lng,lat),...]}:点数组JSON * success{function}:成功回调函数 */ calculateAltitude: function(options) { var positions = []; var points = options.points; /* 构建点位置集合 */ for (var i = 0; i < points.length; i++) { var point = points[i]; positions.push(Cesium.Cartographic.fromDegrees(parseFloat(point.lng), parseFloat(point .lat))); } /* 构建查询 */ var promise = Cesium.sampleTerrain(window['dem'], 14, positions); /* 监听查询完成 */ Cesium.when(promise, function(resData) { var outHeights = []; for (var i = 0; i < resData.length; i++) { outHeights.push(resData[i].height); } if (options.success != undefined) options.success(outHeights); }); } }); /** * 切割相关 */ CrMap.prototype.extend({ /** * 动态改变ClippingPlane距离原点的距离 * @param {Object} plane ClippingPlane实例 */ _createPlaneUpdateFunction: function(plane) { var self = this; return function() { plane.distance = self.planeTargetY + 10; return plane; }; }, /** * 开始切割BIM * @param {Object} tilesetId BIM模型图层Id * @param {String} callback 消息回调 */ openClipBIM: function(tilesetId, callback) { var self = this; //self.planeTargetY = 30; var tileset = window[tilesetId]; if (tileset == undefined) { if (callback != undefined) { callback("先开启BIM图层!"); } } else { var boundingSphere = tileset.get(0).boundingSphere; var clippingPlanes = new Cesium.ClippingPlaneCollection({ planes: [ new Cesium.ClippingPlane(new Cesium.Cartesian3(0, 0, -1), 30) // 平面的方向 以及 平面到原点的距离 ], edgeColor: Cesium.Color.WHITE, // 平面切割时模型的边缘颜色 edgeWidth: 3.0 // 平面切割时模型的边缘宽度 }); tileset.get(0).clippingPlanes = clippingPlanes; //设置可以切割 var radius = boundingSphere.radius; // 长度 for (var i = 0; i < clippingPlanes.length; ++i) { var plane = clippingPlanes.get(i); self.viewer.entities.add({ name: 'entity_clip_bim', position: boundingSphere.center, plane: { dimensions: new Cesium.Cartesian2(radius, radius), material: Cesium.Color.RED.withAlpha(0.1), plane: new Cesium.CallbackProperty(self._createPlaneUpdateFunction( plane), false), outline: true, outlineColor: Cesium.Color.WHITE } }); } /* 缩放到位置 */ self.flyTo(tileset); } }, /** * 关闭BIM切割 */ closeClipBIM: function() { var name = 'entity_clip_bim'; var entities = this.viewer.entities; var delEntitys = []; //循环查找符合条件的Entity for (var i = 0; i < entities.values.length; i++) { if (entities.values[i].name == name) { delEntitys.push(entities.values[i]); } } //删除符合条件的Entity for (var i = 0; i < delEntitys.length; i++) { entities.remove(delEntitys[i]); } } }); /** * 工具相关 */ CrMap.prototype.extend({ /** * 刷新场景 刷新一帧 */ updateSence: function() { this.viewer.scene.requestRender(); }, /** * 飞行至指定位置 * @param {double} longitude 经度 * @param {double} latitude 纬度 * @param {double} altitude 高度 */ zoomTo: function(longitude, latitude, altitude) { var boundingSphere = new Cesium.BoundingSphere(Cesium.Cartesian3.fromDegrees(longitude, latitude, 0), altitude / 3); this.viewer.camera.flyToBoundingSphere(boundingSphere); }, /** * 飞行至指定对象 * @param {Object} obj 对象 */ flyTo: function(obj) { if (obj instanceof Cesium.PrimitiveCollection) { obj = obj.get(0); } this.viewer.flyTo(obj, { offset: new Cesium.HeadingPitchRange(0.0, Cesium.Math.toRadians(-45.0)), }); }, /** * 相机视角飞行到指定位置 * @param {JSON} options 位置信息 * {lng: lat: alt: heading: pitch:} */ flyToo: function(options) { this.viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(options.lng, options.lat, options.alt), orientation: { heading: Cesium.Math.toRadians(options.heading, 0), pitch: Cesium.Math.toRadians(options.pitch), roll: 0.0 }, duration: options.duration == undefined ? 10 : options.duration, complete: function() { if (options.success != undefined) options.success(); }, }) }, /** * 添加图层Id到初始化集合中 * @param {Object} layerId 图层Id */ addBeforeLayerId: function(layerId) { this.beforeLayerIds.push(layerId); }, /** * 设置地图在当前窗口中心点和高度下指北 */ setMapNorth: function() { var height = Math.ceil(this.viewer.camera.positionCartographic.height); var result = this.viewer.camera.pickEllipsoid(new Cesium.Cartesian2(this.viewer.canvas .clientWidth / 2, this.viewer .canvas.clientHeight / 2)); var curPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(result); var lon = curPosition.longitude * 180 / Math.PI; var lat = curPosition.latitude * 180 / Math.PI; var boundingSphere = new Cesium.BoundingSphere(Cesium.Cartesian3.fromDegrees(lon, lat, 0), height / 3); this.viewer.camera.flyToBoundingSphere(boundingSphere); }, /** * 经纬度转换为屏幕坐标 * @param {JSON} point 坐标点 * point格式{lng: lat: alt:} */ wgs84ToScreen: function(point) { var position = Cesium.Cartesian3.fromDegrees(point.lng, point.lat, point.alt); var res = Cesium.SceneTransforms.wgs84ToWindowCoordinates(this.viewer.scene, position); if (res == undefined) { return { x: -500, y: -500, } } else { return { x: res.x - 0, y: res.y - 0, }; } }, /** * 输出当前相机视角参数 */ exportCameraViewParams: function() { var self = this; var g84Position = self._wordToWGS84(self.viewer.camera.position) var result = { lng: g84Position.lng, lat: g84Position.lat, alt: g84Position.alt, pitch: self._arcToDegree(self.viewer.camera.pitch), heading: self._arcToDegree(self.viewer.camera.heading), } return result; }, /** * 计算当前位置距离相机的空间距离 * @param {Object} options 位置 * {lng: lat: alt:} */ calculationToCameraDistance: function(options) { var self = this; var cameraPosition = self.viewer.camera.position; var wgs84Position = Cesium.Cartographic.fromDegrees(options.lng, options.lat, options.alt); var pointPosition = self.viewer.scene.globe.ellipsoid.cartographicToCartesian(wgs84Position); /* 开始计算距离 */ var dx = cameraPosition.x - pointPosition.x; var dy = cameraPosition.y - pointPosition.y; var dz = cameraPosition.z - pointPosition.z; return Math.sqrt(dx * dx + dy * dy + dz * dz); }, /** * 相机飞行位置 * @param {Object} options 设置项 * {lng:经度 lat:纬度 alt:高度} */ flyCameraTo: function(options) { alert(options.lng + "," + options.lat + "," + options.alt) var self = this; var newPosition = self._calculateCameraPosition({ lng: options.lng, lat: options.lat, alt: options.alt, angle: self.angle, }); alert(JSON.stringify(newPosition)); self.viewer.camera.setView({ destination: newPosition, orientation: { heading: Cesium.Math.toRadians(Cesium.Math.toDegrees(self.viewer.camera .heading) + self.angle), pitch: self.viewer.camera.pitch, } }); }, /** * 设置显示范围 * @param {JSON} options 配置项 * lng{double}:经度 * lat{double}:纬度 * alt{double}:高度 * heading{double}:指北角度 度 * pitch{double}:垂直视角 度 * roll{double}:翻滚视角 度 */ setMapRange: function(options) { this.viewer.camera.setView({ destination: Cesium.Cartesian3.fromDegrees(options.lng, options.lat, options.alt), orientation: { //此视角为观察者/相机 heading: options.heading, pitch: Cesium.Math.toRadians(options.pitch), roll: options.roll } }); }, /** * 异步飞行 * @param {JSON} options 配置项 * target{Object}:飞行目的地目标 * duration{int}:飞行持续时间 秒 * radians{double}:旋转角度 度 * isRemove{boolean}:执行完成后是否删除目标 true/false */ asyncFlyTo: function(options) { var self = this; return new Promise((resolve, reject) => { /* 飞行 */ var flyPromise = self.viewer.flyTo(options.target, { duration: options.duration, //飞行持续时间 offset: new Cesium.HeadingPitchRange(0.0, Cesium.Math.toRadians(options .radians)), }); /* 飞行完成 */ flyPromise.then(function(isFly) { if (isFly && options.isRemove && options.target != undefined) { self.viewer.entities.remove(options.target); } resolve(true); }) }); }, /** * 飞向矩形区域 * @param {JSON} options 配置项 * strLng{double}:矩形起始点经度 * strLat{double}:矩形起始点纬度 * endLng{double}:矩形终止点经度 * endLat{double}:矩形终止点纬度 */ flyToRectangle: function(options) { var self = this; this.entities.removeById('flyRectangle'); var extent = Cesium.Rectangle.fromDegrees(options.strLng, options.strLat, options.endLng, options .endLat); /* 创建飞行矩形 */ var flyRectangle = this.entities.add({ id: 'flyRectangle', name: 'flyRectangle', rectangle: { coordinates: extent, material: Cesium.Color.GREEN.withAlpha(0), height: 10.0, outline: false } }); this.asyncFlyTo({ target: flyRectangle, //定位对象 isRemove: false, //定位完成后是否删除 duration: 3, radians: -90, }).then(function(isFly) { if (isFly) { self.asyncFlyTo({ target: flyRectangle, //定位对象 isRemove: true, //定位完成后是否删除 duration: 1, radians: -40, }).then(function(isFly) { if (isFly && options.success != undefined) { options.success(); } }) } }).catch(function(err) { alert(err); }) } }); /** * 特效相关 雨雪雾 */ CrMap.prototype.extend({ /** * 开启下雪 */ _openSnow: function() { return "uniform sampler2D colorTexture;\n\ varying vec2 v_textureCoordinates;\n\ \n\ float snow(vec2 uv,float scale)\n\ {\n\ float time = czm_frameNumber / 60.0;\n\ float w=smoothstep(1.,0.,-uv.y*(scale/10.));if(w<.1)return 0.;\n\ uv+=time/scale;uv.y+=time*2./scale;uv.x+=sin(uv.y+time*.5)/scale;\n\ uv*=scale;vec2 s=floor(uv),f=fract(uv),p;float k=3.,d;\n\ p=.5+.35*sin(11.*fract(sin((s+p+scale)*mat2(7,3,6,5))*5.))-f;d=length(p);k=min(d,k);\n\ k=smoothstep(0.,k,sin(f.x+f.y)*0.01);\n\ return k*w;\n\ }\n\ \n\ void main(void){\n\ vec2 resolution = czm_viewport.zw;\n\ vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);\n\ vec3 finalColor=vec3(0);\n\ float c = 0.0;\n\ c+=snow(uv,30.)*.0;\n\ c+=snow(uv,20.)*.0;\n\ c+=snow(uv,15.)*.0;\n\ c+=snow(uv,10.);\n\ c+=snow(uv,8.);\n\ c+=snow(uv,6.);\n\ c+=snow(uv,5.);\n\ finalColor=(vec3(c)); \n\ gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(finalColor,1), 0.5); \n\ \n\ }\n\ "; }, /** * 开启下雨 */ _openRain: function() { return "uniform sampler2D colorTexture;\n\ varying vec2 v_textureCoordinates;\n\ \n\ float hash(float x){\n\ return fract(sin(x*133.3)*13.13);\n\ }\n\ \n\ void main(void){\n\ \n\ float time = czm_frameNumber / 60.0;\n\ vec2 resolution = czm_viewport.zw;\n\ \n\ vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);\n\ vec3 c=vec3(.6,.7,.8);\n\ \n\ float a=-.4;\n\ float si=sin(a),co=cos(a);\n\ uv*=mat2(co,-si,si,co);\n\ uv*=length(uv+vec2(0,4.9))*.3+1.;\n\ \n\ float v=1.-sin(hash(floor(uv.x*100.))*2.);\n\ float b=clamp(abs(sin(20.*time*v+uv.y*(5./(2.+v))))-.95,0.,1.)*20.;\n\ c*=v*b; \n\ \n\ gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(c,1), 0.5); \n\ }\n\ "; }, /** * 打开雾 */ _openFog: function() { return 'uniform sampler2D colorTexture;\n' + ' uniform sampler2D depthTexture;\n' + ' varying vec2 v_textureCoordinates;\n' + ' void main(void)\n' + ' {\n' + ' vec4 origcolor=texture2D(colorTexture, v_textureCoordinates);\n' + ' vec4 fogcolor=vec4(0.8,0.8,0.8,0.5);\n' + ' float depth = czm_readDepth(depthTexture, v_textureCoordinates);\n' + ' vec4 depthcolor=texture2D(depthTexture, v_textureCoordinates);\n' + ' float f=(depthcolor.r-0.55)/0.5;\n' + ' if(f<0.0) f=0.0;\n' + ' else if(f>1.0) f=1.0;\n' + ' gl_FragColor = mix(origcolor,fogcolor,f);\n' + ' }'; }, /** * 开启雪模式 */ openSnow: function() { var self = this; var collection = self.viewer.scene.postProcessStages; var fs_snow = self._openSnow(); self.snowStage = new Cesium.PostProcessStage({ name: 'czm_snow', fragmentShader: fs_snow }); collection.add(self.snowStage); self.viewer.scene.requestRenderMode = false; //关闭主动渲染 否则无法下雪持续 self.viewer.scene.skyAtmosphere.hueShift = -0.8; self.viewer.scene.skyAtmosphere.saturationShift = -0.7; self.viewer.scene.skyAtmosphere.brightnessShift = -0.33; self.viewer.scene.fog.density = 0.001; self.viewer.scene.fog.minimumBrightness = 0.8; }, /** * 开启雨的模式 */ openRain: function() { var self = this; var collection = self.viewer.scene.postProcessStages; var fs_snow = self._openRain(); self.rainStage = new Cesium.PostProcessStage({ name: 'czm_rain', fragmentShader: fs_snow }); collection.add(self.rainStage); self.viewer.scene.requestRenderMode = false; //关闭主动渲染 否则无法下雪持续 self.viewer.scene.skyAtmosphere.hueShift = -0.8; self.viewer.scene.skyAtmosphere.saturationShift = -0.7; self.viewer.scene.skyAtmosphere.brightnessShift = -0.33; self.viewer.scene.fog.density = 0.001; self.viewer.scene.fog.minimumBrightness = 0.8; }, /** * 开启雾模式 */ openFog: function() { var self = this; var collection = self.viewer.scene.postProcessStages; var fs_snow = self._openFog(); self.fogStage = new Cesium.PostProcessStage({ name: 'czm_fog', fragmentShader: fs_snow }); collection.add(self.fogStage); self.viewer.scene.requestRenderMode = false; //关闭主动渲染 否则无法下雪持续 self.viewer.scene.skyAtmosphere.hueShift = -0.8; self.viewer.scene.skyAtmosphere.saturationShift = -0.7; self.viewer.scene.skyAtmosphere.brightnessShift = -0.33; self.viewer.scene.fog.density = 0.001; self.viewer.scene.fog.minimumBrightness = 0.8; }, /** * 关闭雨 */ closeRain: function() { var self = this; if (this.rainStage) { this.viewer.scene.postProcessStages.remove(this.rainStage); this.rainStage = undefined; // setTimeout(function(){ // self.viewer.scene.requestRenderMode = true; //启动主动渲染 否则无法下雪持续 // },1000); } }, /** * 关闭雪 */ closeSnow: function() { var self = this; if (this.snowStage) { this.viewer.scene.postProcessStages.remove(this.snowStage); this.snowStage = undefined; // setTimeout(function(){ // self.viewer.scene.requestRenderMode = true; //启动主动渲染 否则无法下雪持续 // },1000); } }, /** * 关闭雾 */ closeFog: function() { var self = this; if (this.fogStage) { this.viewer.scene.postProcessStages.remove(this.fogStage); this.fogStage = undefined; // setTimeout(function(){ // self.viewer.scene.requestRenderMode = true; //启动主动渲染 否则无法下雪持续 // },1000); } }, }); /** * 调起查询工具 */ CrMap.prototype.extend({ /** * 点查询 */ queryPoint: function() { this.actionType = ActionType.queryAttribute; }, }); /** * 矢量服务查询 */ CrMap.prototype.extend({ /** * 获取tile分级 * @param {Object} height 高度 */ _getLevel: function(height) { if (height > 48000000) { return 0; } else if (height > 24000000) { return 1; } else if (height > 12000000) { return 2; } else if (height > 6000000) { return 3; } else if (height > 3000000) { return 4; } else if (height > 1500000) { return 5; } else if (height > 750000) { return 6; } else if (height > 375000) { return 7; } else if (height > 187500) { return 8; } else if (height > 93750) { return 9; } else if (height > 46875) { return 10; } else if (height > 23437.5) { return 11; } else if (height > 11718.75) { return 12; } else if (height > 5859.38) { return 13; } else if (height > 2929.69) { return 14; } else if (height > 1464.84) { return 15; } else if (height > 732.42) { return 16; } else if (height > 366.21) { return 17; } else { return 18; } }, /** * 点击查询矢量数据 * @param {Object} position 鼠标点击位置 */ _queryVectorLayer(position) { var self = this; //测试 打印查询的图层看看 // for(var i=0;i= 1) { flog = true; } } self.updateSence(); // return { // glowPower: 0.25, // color: Cesium.Color.RED.withAlpha(0.3), // }; return Cesium.Color.RED.withAlpha(x); }, false)); }, /** * @param {JSON} options * {name: point:{lng,lat}} */ addSelectPointEntity: function(options) { var self = this; var a = true; var n = true; var o = true; var markerOpacity = 1; var pixelSize = 3; var outLineOpacity = 0.7; var ptColor = Cesium.Color.RED; var pixelMax = 50; var pointEntity = { name: options.name, position: Cesium.Cartesian3.fromDegrees(options.point.lng, options.point.lat), point: { heightReference: 50, color: new Cesium.CallbackProperty(() => { self.updateSence(); return a ? (markerOpacity -= .03, markerOpacity <= 0 && (a = false)) : (markerOpacity = 1, a = true), ptColor.withAlpha(markerOpacity) }, false), pixelSize: new Cesium.CallbackProperty((time, result) => { self.updateSence(); return n ? (pixelSize += 1, pixelSize >= pixelMax && (n = false)) : (pixelSize = 3, n = true), pixelSize }, false), // outlineColor: new Cesium.CallbackProperty(() => { // self.updateSence(); // return o ? (outLineOpacity -= .035, // outLineOpacity <= 0 && (o = false)) : (outLineOpacity = .7, // o = true), // ptColor.withAlpha(outLineOpacity) // }, false), // outlineWidth: 2, scaleByDistance: new Cesium.NearFarScalar(1200, 1, 5200, 0.4), } }; //加入图层 self.entities.add(pointEntity); //更新场景 self.updateSence(); }, /** * 添加面对像 * @param {JSON} options * id:添加的面对象Id * config:(JSON){name:图层名称 geo:矢量数据} * points:[{lng,lat},...] * color:{r: g: b: a:}} * description:(JSON) */ addPolygonEntityTest: function(options) { var self = this; //解析线坐标 var points = []; for (var i = 0; i < options.points.length; i++) { points.push(Cesium.Cartesian3.fromDegrees(options.points[i].lng, options.points[i].lat)); } var polygonEntity = new Cesium.Entity({ name: options.config.name, id: options.id, polygon: { hierarchy: { positions: points, }, material: self._toColor(options.color.r, options.color.g, options.color.b, options .color.a), classificationType: Cesium.ClassificationType.BOTH, } }); //加入图层 self.viewer.entities.add(polygonEntity); }, /** * 添加面对像 * @param {JSON} options * id:添加的面对象Id * config:(JSON){name:图层名称 geo:矢量数据} * points:[{lng,lat},...] * color:{r: g: b: a:}} * description:(JSON) */ addPolygonEntity: function(options) { var self = this; //解析线坐标 var points = []; var pts = []; for (var i = 0; i < options.points.length; i++) { points.push(Cesium.Cartesian3.fromDegrees(options.points[i].lng, options.points[i].lat)); pts.push({ lng: options.points[i].lng, lat: options.points[i].lat, }); } var polygonEntity = new Cesium.Entity({ name: JSON.stringify({ name: options.config.name, geometry: { type: 'polygon', pts: [pts], }, }), id: options.id, description: JSON.stringify(options.description), polygon: { hierarchy: { positions: points, }, material: self._toColor(options.color.r, options.color.g, options.color.b, options .color.a), classificationType: Cesium.ClassificationType.BOTH, } }); //加入图层 self.viewer.entities.add(polygonEntity); }, /** * 添加点实体 * @param {JSON} options 数据项 * {name:实体名称 lng:经度 lat:纬度} * point:{color:'0,0,0,1' outlineColor:'0,0,0,1' size: outlineWidth:} * label:{text: size: family: color: offset:[,]} * billboard:{img: scale:} */ addPoint: function(options) { var self = this; var point = Cesium.Cartesian3.fromDegrees(options.lng, options.lat, 200); var pointEntity = new Cesium.Entity({ name: options.name, position: point, }); var configPoint = options.point; var configLabel = options.label; var configBillboard = options.billboard; /* 配置点信息 */ if (configPoint != undefined) { pointEntity.point = { color: Cesium.Color.fromCssColorString('rgba(' + configPoint.color + ')'), pixelSize: configPoint.size, outlineColor: Cesium.Color.fromCssColorString('rgba(' + configPoint.outlineColor + ')'), outlineWidth: configPoint.outlineWidth, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, } } /* 配置广告牌信息 */ if (configBillboard != undefined) { pointEntity.billboard = { image: configBillboard.img, scale: configBillboard.scale, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.BASELINE, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, }; } /* 配置标签 */ if (configLabel != undefined) { pointEntity.label = { text: configLabel.text, font: configLabel.size + 'px ' + configLabel.family, scale: 0.5, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, fillColor: Cesium.Color.WHITE, outlineColor: Cesium.Color.fromCssColorString('rgba(' + configLabel.color + ')'), outlineWidth: 4, style: Cesium.LabelStyle.FILL_AND_OUTLINE, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.center, pixelOffset: new Cesium.Cartesian2(configLabel.offset[0], configLabel.offset[1]), showBackground: false, } } /* 添加实体 */ self.entities.add(pointEntity); /* 更新场景 */ self.updateSence(); }, /** * 获取旋转值 */ _getRotationValue: function() { var self = this; return function() { self.areaRotation += 0.005; return self.areaRotation; } }, /** * 添加旋转区域 * @param {JSON} options 配置项 * strLng{double}:矩形起始点经度 * strLat{double}:矩形起始点纬度 * endLng{double}:矩形终止点经度 * endLag{double}:矩形终止点纬度 * northImage{String}:指北照片Url * scaleImage{String}:旋转照片Url */ addRotateArea: function(options) { var self = this; // alert(self.serverUrl + options.northImage); self.entities.add({ name: "rotateArea", rectangle: { coordinates: Cesium.Rectangle.fromDegrees(options.strLng, options.strLat, options .endLng, options.endLat), material: self.serverUrl + options.northImage, classificationType: Cesium.ClassificationType.TERRAIN, }, }); // self.entities.add({ // name: "rotateArea", // rectangle: { // coordinates: Cesium.Rectangle.fromDegrees(options.strLng, options.strLat, options // .endLng, options.endLat), // material: self.serverUrl + options.scaleImage, // rotation: new Cesium.CallbackProperty(self._getRotationValue(), false), // stRotation: new Cesium.CallbackProperty(self._getRotationValue(), false), // classificationType: Cesium.ClassificationType.TERRAIN, // }, // }); }, /** * 从集合中删除具有提供的ID的实体 * 如果已删除项目,则为true;如果集合中不存在具有提供的ID的项目,则为false * @param {Object} entityId 实体Id */ removeEntityById: function(entityId) { var isDel = this.viewer.entities.removeById(entityId); this.updateSence(); return isDel; }, /** * 根据名称删除实体 * @param {Object} entityName 实体名称 */ removeEntityByName: function(entityName) { this._removeEntities(entityName); }, }); /** * OD线相关 */ CrMap.prototype.extend({ /** * 计算间隔点 * @param {JSON} options * @param {Array} resultOut */ _parabolaEquation: function(options, resultOut) { //方程 y=-(4h/L^2)*x^2+h h:顶点高度 L:横纵间距较大者 var h = options.height && options.height < 5000 ? options.height : 5000; var L = Math.abs(options.pt1.lon - options.pt2.lon) > Math.abs(options.pt1.lat - options.pt2 .lat) ? Math.abs(options.pt1.lon - options.pt2.lon) : Math.abs(options.pt1.lat - options.pt2.lat); var num = options.num && options.num > 50 ? options.num : 50; var result = []; var tempResult = []; //临时数组 var dlt = L / num; var addHeight = options.pt1.alt > options.pt2.alt ? options.pt1.alt : options.pt2.alt; var maxHeight = addHeight + h; var minHeight1 = options.pt1.alt; var minHeight2 = options.pt2.alt; if (Math.abs(options.pt1.lon - options.pt2.lon) > Math.abs(options.pt1.lat - options.pt2 .lat)) { //以lon为基准 var delLat = (options.pt2.lat - options.pt1.lat) / num; if (options.pt1.lon - options.pt2.lon > 0) { dlt = -dlt; } for (var i = 1; i < num; i++) { var tempH = h - Math.pow((-0.5 * L + Math.abs(dlt) * i), 2) * 4 * h / Math.pow(L, 2); var lon = options.pt1.lon + dlt * i; var lat = options.pt1.lat + delLat * i; var alt = undefined; if (Math.abs(dlt) * i == 0.5 * L) { alt = maxHeight; } else if (Math.abs(dlt) * i < 0.5 * L) { //说明是抛物线左侧 alt = ((maxHeight - minHeight1) / h) * tempH + minHeight1; } else { //说明是抛物线右侧 alt = ((maxHeight - minHeight2) / h) * tempH + minHeight2; } tempResult.push([lon, lat, alt]); } } else { //以lat为基准 var delLon = (options.pt2.lon - options.pt1.lon) / num; if (options.pt1.lat - options.pt2.lat > 0) { dlt = -dlt; } for (var i = 1; i < num; i++) { var tempH = h - Math.pow((-0.5 * L + Math.abs(dlt) * i), 2) * 4 * h / Math.pow(L, 2); var lon = options.pt1.lon + delLon * i; var lat = options.pt1.lat + dlt * i; var alt = undefined; if (Math.abs(dlt) * i == 0.5 * L) { alt = maxHeight; } else if (Math.abs(dlt) * i < 0.5 * L) { //说明是抛物线左侧 alt = ((maxHeight - minHeight1) / h) * tempH + minHeight1; } else { //说明是抛物线右侧 alt = ((maxHeight - minHeight2) / h) * tempH + minHeight2; } tempResult.push([lon, lat, alt]); } } /* 对结果进行处理 */ result.push([options.pt1.lon, options.pt1.lat, options.pt1.alt]); for (var i = 0; i < tempResult.length; i++) { result.push(tempResult[i]); } result.push([options.pt2.lon, options.pt2.lat, options.pt2.alt]); if (resultOut != undefined) { resultOut = result; } return result; }, /** * 设置OD线 * @param {JSON} center 中心点 * @param {Array(JSON)} cities 到达点 * @param {String} name 添加的OD线的名称 */ addODLine: function(center, cities, name) { var self = this; //Cesium.Color.BLUE var material = new Cesium.PolylineTrailLinkMaterialProperty(self._toColor(0, 0, 255, 1.0), 4000); /* 添加OD线 */ for (var j = 0; j < cities.length; j++) { var points = self._parabolaEquation({ pt1: center, pt2: cities[j], height: 800, num: 10 }); var pointArr = []; for (var i = 0; i < points.length; i++) { pointArr.push(points[i][0], points[i][1], points[i][2]); } self.entities.add({ name: name, polyline: { positions: Cesium.Cartesian3.fromDegreesArrayHeights(pointArr), width: 2, material: material } }); } /* 添加目标点 */ self.entities.add({ name: name, position: Cesium.Cartesian3.fromDegrees(center.lon, center.lat, center.alt), point: { pixelSize: 6, color: Cesium.Color.BLUE } }); /* 添加来源点数组 */ for (var i = 0; i < cities.length; i++) { self.entities.add({ name: name, position: Cesium.Cartesian3.fromDegrees(cities[i].lon, cities[i].lat, cities[i] .alt), point: { pixelSize: 6, color: Cesium.Color.RED } }); } self.viewer.scene.requestRenderMode = false; //开启主动刷新 }, /** * 移除OD线 * @param {Object} name OD线的名称 */ removeODLine: function(name) { this._removeEntities(name); } }); /** * 地图案件查询相关 */ CrMap.prototype.extend({ /** * 案件查询 点方式查询 点击事件 * @param {Object} event 点击事件 */ _eventCasePointQueryMouseClick: function(event) { var self = this; var ray = this.viewer.camera.getPickRay(event.position); var cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene); this.measurePoints.push(cartesian); //添加点和标注 this.entities.add({ name: 'measure', position: self.measurePoints[self.measurePoints.length - 1], point: { pixelSize: self.measurePointStyle.pixelSize, color: self.measurePointStyle.color, outlineColor: self.measurePointStyle.outlineColor, outlineWidth: self.measurePointStyle.outlineWidth, }, }); //还原工具 以免多次点击 this.actionType = ActionType.non; //刷新场景 this.updateSence(); //主动刷新场景 //弹出气泡查询窗口 var g84Coord = this._wordToWGS84(cartesian); //世界坐标转经纬度坐标 if (this.onPopoverQueryTool != undefined) { this.onPopoverQueryTool({ x: event.position.x, y: event.position.y, lng: g84Coord.lng, lat: g84Coord.lat, alt: g84Coord.alt, extent: g84Coord.lng + "," + g84Coord.lat, queryType: 'point', }); } }, /** * 案件查询 区域方式查询 点击事件 * @param {Object} event 点击事件 */ _eventCasePolygonQueryMouseClick: function(event) { var self = this; var ray = this.viewer.camera.getPickRay(event.position); var cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene); this.measurePoints.push(cartesian); //添加绘制面 if (this.measurePoints.length > 2 && !Cesium.defined(self.measurePolygon)) { /* 添加一个面 */ self.measurePolygon = new Cesium.Entity({ name: 'measure', polygon: { show: true, hierarchy: new Cesium.CallbackProperty(self._measureUpdatePolygon(), false), material: Cesium.Color.GREEN.withAlpha(0.3), } }) self.entities.add(self.measurePolygon); } //添加点 this.entities.add({ name: 'measure', position: self.measurePoints[self.measurePoints.length - 1], point: { pixelSize: self.measurePointStyle.pixelSize, color: self.measurePointStyle.color, outlineColor: self.measurePointStyle.outlineColor, outlineWidth: self.measurePointStyle.outlineWidth, }, }); //判断是否显示查询按钮气泡窗口 if (self.measurePoints.length >= 4) { /* 转换全部坐标点 */ var queryExtent = undefined; for (var i = 0; i < self.measurePoints.length; i++) { var g84 = this._wordToWGS84(self.measurePoints[i]); //世界坐标转经纬度坐标 if (queryExtent == undefined) queryExtent = g84.lng + "," + g84.lat; else queryExtent += "," + g84.lng + "," + g84.lat; } var g84Coord = this._wordToWGS84(cartesian); //世界坐标转经纬度坐标 if (this.onPopoverQueryTool != undefined) { this.onPopoverQueryTool({ x: event.position.x, y: event.position.y, lng: g84Coord.lng, lat: g84Coord.lat, alt: g84Coord.alt, extent: queryExtent, queryType: 'polygon', }); } } this.updateSence(); //主动刷新场景 }, /** * 地图上案件点查询 * @param {function} callback 查询提示信息回调 */ casePointQuery: function(callback) { this._measureInit(); this.actionType = ActionType.casePointQuery; if (callback != undefined) { callback("单击案件位置查询!"); } }, /** * 地图上案件区域查询 * @param {Object} callback 查询提示信息回调 */ casePolygonQuery: function(callback) { this._measureInit(); this.actionType = ActionType.casePolygonQuery; if (callback != undefined) { callback("单击绘制查询区域,点击开始查询按钮进行查询!"); } } }); /** * 测量相关 */ CrMap.prototype.extend({ /** * 添加广告牌和标签 * @param {JSON} options * position{Cartesian3}:位置 * text{string}:标签 */ _measureAddBillboardAndLabel: function(options) { var self = this; var entity = new Cesium.Entity({ name: 'measure', position: options.position, billboard: { image: self.serverUrl + 'ico_measure_location.png', horizontalOrigin: Cesium.HorizontalOrigin.center, verticalOrigin: Cesium.VerticalOrigin.bottom, scale: 0.5, pixelOffset: new Cesium.Cartesian2(0, -10), disableDepthTestDistance: Number.POSITIVE_INFINITY, } }); /* 判断是否添加标注 */ if (options.text != undefined) { entity.label = { text: options.text, font: '12px sans-serif', fillColor: this._toColor(255, 255, 255, 1.0), outlineColor: this._toColor(0, 154, 94, 1.0), style: Cesium.LabelStyle.FILL_AND_OUTLINE, outlineWidth: 1.0, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, pixelOffset: new Cesium.Cartesian2(0, -28), showBackground: true, backgroundColor: this._toColor(0, 0, 0, 0.6), disableDepthTestDistance: Number.POSITIVE_INFINITY, } } this.entities.add(entity); }, /** * 添加测量多段线 */ _measureAddPolyline: function() { if (!Cesium.defined(this.measurePolyline)) { this.measurePolyline = new Cesium.Entity({ name: 'measure', polyline: { show: true, positions: new Cesium.CallbackProperty(this._measureUpdatePolyline(), false), material: this._toColor(0, 255, 0, 0.6), width: 2, clampToGround: true, //开启贴地 如果有模型则贴模型 } }) this.entities.add(this.measurePolyline); } }, /** * 添加一个测量面 */ _measureAddPolygon: function() { if (!Cesium.defined(this.measurePolygon)) { this.measurePolygon = new Cesium.Entity({ name: 'measure', polygon: { show: true, hierarchy: new Cesium.CallbackProperty(this._measureUpdatePolygon(), false), material: Cesium.Color.GREEN.withAlpha(0.3), classificationType: Cesium.ClassificationType.BOTH, } }) this.entities.add(this.measurePolygon); } }, /** * 测量长度的鼠标点击事件 * @param {Object} event 事件 */ _eventMeasureLengthMouseClick: function(event) { var self = this; /* 根据屏幕位置获取经度、纬度和高度信息 */ var resLocation = this._getLocation(event.position); /* 创建空间三维坐标 */ var cartesian = Cesium.Cartesian3.fromDegrees(resLocation.lng, resLocation.lat, resLocation.height); /* 将创建的空间位置存储到点集合 */ this.measurePoints.push(cartesian.clone()); if (this.measurePoints.length > 1) { this.measureLengthResult = this._measureSpaceDistance(this.measurePoints); } else { this.measureLengthResult = "起点"; } /* 添加线 */ this._measureAddPolyline(); /* 添加广告牌定位标签和标注 */ this._measureAddBillboardAndLabel({ position: self.measurePoints[self.measurePoints.length - 1], text: self.measureLengthResult, }); this.updateSence(); //主动刷新场景 }, /** * 测量面积的鼠标点击事件 * @param {Object} event 事件 */ _eventMeasureAreaMouseClick: function(event) { var self = this; /* 根据屏幕位置获取经度、纬度和高度信息 */ var resLocation = this._getLocation(event.position); /* 创建空间三维坐标 */ var cartesian = Cesium.Cartesian3.fromDegrees(resLocation.lng, resLocation.lat, resLocation.height); /* 将创建的空间位置存储到点集合 */ this.measurePoints.push(cartesian.clone()); /* 添加点到计算集合 */ this.measureTempPoints.push({ lon: resLocation.lng, lat: resLocation.lat, hei: resLocation.height }); if (this.measurePoints.length > 2) { this.measureAreaResult = this._measureArea(this.measureTempPoints); //计算面积 if (this.measurePoints.length == 3) { this._measureAddPolygon(); //添加测量面 /* 添加广告牌定位标签和标注 */ this._measureAddBillboardAndLabel({ position: self.measurePoints[0], text: new Cesium.CallbackProperty(self._measureUpdateLabelText(), false), }); } else { /* 添加广告牌定位标签 */ this._measureAddBillboardAndLabel({ position: self.measurePoints[self.measurePoints.length - 1], }); } } else { /* 添加广告牌定位标签 */ this._measureAddBillboardAndLabel({ position: self.measurePoints[self.measurePoints.length - 1], }); } this.updateSence(); //主动刷新场景 }, /** * 测量长度点集合属性回调 */ _measureUpdatePolyline: function() { var self = this; return function() { return self.measurePoints; }; }, /** * 测量长度更新标签回调位置 */ _measureUpdateLabel: function() { var self = this; return function() { return self.measurePoints[self.measurePoints.length - 1]; }; }, /** * 测量长度更新标签回调内容 */ _measureUpdateLabelText: function() { var self = this; return function() { if (self.measureAreaResult > 100000) { return (self.measureAreaResult / 100000).toFixed(2) + "km²"; } else { return self.measureAreaResult.toFixed(2) + "m²"; } }; }, /** * 测量面积点集合属性回调 */ _measureUpdatePolygon: function() { var self = this; return function() { return { positions: self.measurePoints, }; }; }, /** * 测量长度的鼠标移动事件 * @param {Object} event 事件 */ _eventMeasureLengthMouseMove: function(event) { var self = this; var ray = this.viewer.camera.getPickRay(event.endPosition); var cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene); if (self.measurePoints.length > 1) { self.measurePoints.pop(); self.measurePoints.push(cartesian); } }, /** * 测量结束事件 * @param {Object} event 事件 */ _eventMeasureEnd: function(event) { this.actionType = ActionType.non; this.measurePoints.pop(); this.viewer.scene.requestRenderMode = true; //停止主动刷新 //this.updateSence(); //主动刷新以下 }, /** * 计算距离 * @param {Object} positions 点集合 */ _measureSpaceDistance: function(positions) { var distance = 0; for (var i = 0; i < positions.length - 1; i++) { var point1cartographic = Cesium.Cartographic.fromCartesian(positions[i]); var point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1]); /**根据经纬度计算出距**/ var geodesic = new Cesium.EllipsoidGeodesic(); geodesic.setEndPoints(point1cartographic, point2cartographic); var s = geodesic.surfaceDistance; //返回两点之间的距离 s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic .height, 2)); distance = distance + s; } if (distance < 1000) return distance.toFixed(2) + "米"; else return (distance / 1000).toFixed(2) + "公里"; }, /** * 计算面积 * @param {Object} points 点集合 */ _measureArea: function(points) { var self = this; var res = 0; // for (var i = 0; i < tempPoints.length; i++) { // console.log("i = " + i + " value = " + JSON.stringify(tempPoints[i])); // } //拆分三角曲面 for (var i = 0; i < points.length - 2; i++) { var j = (i + 1) % points.length; var k = (i + 2) % points.length; var totalAngle = self._measureAreaAngle(points[i], points[j], points[k]); var dis_temp1 = self._measureAreaDistance(self.measurePoints[i], self.measurePoints[j]); var dis_temp2 = self._measureAreaDistance(self.measurePoints[j], self.measurePoints[k]); res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle)); // console.log(res); } return res; }, /** * 计算角度 * @param {Object} p1 点1 * @param {Object} p2 点2 * @param {Object} p3 点3 */ _measureAreaAngle: function(p1, p2, p3) { var bearing21 = this._measureAreaBearing(p2, p1); var bearing23 = this._measureAreaBearing(p2, p3); var angle = bearing21 - bearing23; if (angle < 0) { angle += 360; } return angle; }, /** * 计算方向 * @param {Object} from 起始 * @param {Object} to 终止 */ _measureAreaBearing: function(from, to) { var radiansPerDegree = Math.PI / 180.0; //角度转化为弧度(rad) var degreesPerRadian = 180.0 / Math.PI; //弧度转化为角度 var lat1 = from.lat * radiansPerDegree; var lon1 = from.lon * radiansPerDegree; var lat2 = to.lat * radiansPerDegree; var lon2 = to.lon * radiansPerDegree; var angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin( lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2)); if (angle < 0) { angle += Math.PI * 2.0; } angle = angle * degreesPerRadian; //角度 return angle; }, /** * 计算两点之间的距离 * @param {Object} point1 点1 * @param {Object} point2 点2 */ _measureAreaDistance(point1, point2) { var point1cartographic = Cesium.Cartographic.fromCartesian(point1); var point2cartographic = Cesium.Cartographic.fromCartesian(point2); /**根据经纬度计算出距离**/ var geodesic = new Cesium.EllipsoidGeodesic(); geodesic.setEndPoints(point1cartographic, point2cartographic); var s = geodesic.surfaceDistance; //console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2))); //返回两点之间的距离 s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic .height, 2)); return s; }, /** * 清除测量结果 */ _measureRemoveResult: function() { this._removeEntities('measure'); }, /** * 测量初始化 */ _measureInit: function() { this.measurePoints = []; //测量数组 this.measureTempPoints = []; //面积计算数组 this.measurePolyline = undefined; //测量线 this.measurePolygon = undefined; //测量线 this.measureDistanceResult = 0; //测量长度 this.measureAreaResult = 0; //测量面积 this._measureRemoveResult(); }, /** * @param {string} callback 回调消息 */ measureLength: function(callback) { this._measureInit(); this.actionType = ActionType.measureLength; if (callback != undefined) { callback("单击开始测量!"); } }, /** * @param {string} callback 回调消息 */ measureArea: function(callback) { this._measureInit(); this.actionType = ActionType.measureArea; if (callback != undefined) { callback("单击开始面积测量!"); } }, /** * 测量初始化 * @param {function} callback 回调函数 */ measureClear: function(callback) { this._measureInit(); this.actionType = ActionType.non; if (callback != undefined) callback(); }, }); /** * 路径飞行相关 */ CrMap.prototype.extend({ /** * */ _getMapCenter: function() { /* 获取当前视图的可视范围 west西经 south南纬 east东经 north北纬 以弧度表示*/ var rectangle = this.viewer.camera.computeViewRectangle(); /* 计算中心点 */ var cGraphic = Cesium.Rectangle.center(rectangle); /* 计算高度 */ var height = this.viewer.scene.globe.getHeight(cGraphic); cGraphic.height = height; /* 制图表达转换为笛卡尔坐标 */ var point = Cesium.Cartographic.toCartesian(cGraphic); /* 笛卡尔坐标系转换为WGS84坐标系 */ var rg84Point = Cesium.Cartographic.fromCartesian(point); /* 返回 */ return { lng: (Cesium.Math.toDegrees(rectangle.west) + Cesium.Math.toDegrees(rectangle.east)) / 2, lat: (Cesium.Math.toDegrees(rectangle.south) + Cesium.Math.toDegrees(rectangle.north)) / 2, alt: rg84Point.height, }; }, /** * 计算当前相机位置基于给定基础点旋转一定角度后的位置信息 * @param {JSON} options * {lng: lat: alt: angle:} * return{x: y: z:} */ _calculateCameraPosition: function(options) { var self = this; /* 两个点 */ var point = Cesium.Cartesian3.fromDegrees(options.lng, options.lat, options.alt); var cameraPosition = self.viewer.camera.position; /* 计算参考点的地面法向量 */ var chicB = Cesium.Cartographic.fromCartesian(point); //转成以弧度表示的数据 chicB.height = 0; var dB = Cesium.Cartographic.toCartesian(chicB); //此点其实为地面点对应的投影平面上的点 //normalize 对输入的坐标进行标准化处理 subtract计算两个笛卡尔的分量差异 var normaB = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(dB, point, new Cesium .Cartesian3()), new Cesium.Cartesian3()); /* 构造基于B的法向量旋转90度的矩阵 */ //计算表示围绕轴旋转的四元数 var Q = Cesium.Quaternion.fromAxisAngle(normaB, Cesium.Math.toRadians(options.angle)); //根据提供的四元数计算3x3旋转矩阵 var m3 = Cesium.Matrix3.fromQuaternion(Q); //从Matrix3计算代表旋转的Matrix4 var m4 = Cesium.Matrix4.fromRotationTranslation(m3); /* 计算相机相对于基础点的位置 */ var A1 = Cesium.Cartesian3.subtract(cameraPosition, point, new Cesium.Cartesian3()); /* 对计算后的点应用旋转矩阵 计算矩阵与 Cartesian3 的乘积*/ var p = Cesium.Matrix4.multiplyByPoint(m4, A1, new Cesium.Cartesian3()); /* 新相机位置的坐标 */ var p2 = Cesium.Cartesian3.add(p, point, new Cesium.Cartesian3()); return p2; }, // lng: 117.981144, // lat: 36.314221, // alt: 300, /** * 开始路径飞行 为了尝试使用点击事件确定中心点 则改为利用屏幕坐标进行飞行 * @param {Object} event 鼠标点击事件 */ _startFlightAround: function(event) { var self = this; var ray = self.viewer.camera.getPickRay(event.position); var cartesian = self.viewer.scene.globe.pick(ray, self.viewer.scene); if (cartesian == undefined) { return; } //世界坐标转地理坐标(弧度) var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian); //弧度转换为度 var point = [cartographic.longitude / Math.PI * 180, cartographic.latitude / Math .PI * 180 ]; if (self.flightListner == undefined) { /* 设置当前时间为起始时间 */ var startTime = Cesium.JulianDate.fromDate(new Date()); /* 设置当前时间+1000秒为结束时间 */ var stopTime = Cesium.JulianDate.addSeconds(startTime, 1000, new Cesium.JulianDate()); /* 设置Cesium固定时钟的起始时间 */ self.viewer.clock.startTime = startTime.clone(); /* 设置Cesium固定时钟的终止时间 */ self.viewer.clock.stopTime = stopTime.clone(); /* 设置Cesium固定时钟的当前时间 */ self.viewer.clock.currentTime = startTime.clone(); /* UNBOUNDED到达终止时间后继续读秒 CLAMPED达到终止时间后停止 LOOP_STOP到达终止时间后重复 */ self.viewer.clock.clockRange = Cesium.ClockRange.CLAMPED; /* 用于确定每次通话需要多少时间的常数 */ self.viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; /* 设置动画监听 */ self.flightListner = function eventClock() { var newPosition = self._calculateCameraPosition({ lng: point[0], lat: point[1], alt: 300, angle: self.angle, }); self.viewer.camera.setView({ destination: newPosition, orientation: { heading: Cesium.Math.toRadians(Cesium.Math.toDegrees(self.viewer .camera .heading) + self.angle), pitch: self.viewer.camera.pitch, } }); } self.viewer.clock.onTick.addEventListener(self.flightListner); } }, /** * 调起环飞工具 */ flightAround: function() { this.actionType = ActionType.flightAround; } }); /** * 动态Div标签相关 */ CrMap.prototype.extend({ /** * 向地图中添加标签 * @param {JSON} options 配置项 * title{string}:标题 * sup{string}:子标题 * lng{float}:经度 * lat{float}:纬度 * alt{float}:高度 */ appendLabelToMap: function(options) { var self = this; var points = [{ lng: options.lng, lat: options.lat, }]; self.calculateAltitude({ points: points, success: function(heights) { var screenPoint = self.wgs84ToScreen({ lng: options.lng, lat: options.lat, alt: heights[0], }); // /* 添加一个点 用于验证位置是否正确 */ // var point = Cesium.Cartesian3.fromDegrees(options.lng, options.lat, heights[0]); // var pointEntity = new Cesium.Entity({ // name: 'test', // position: point, // point: { // color: Cesium.Color.CRIMSON, // pixelSize: 9, // outlineColor: Cesium.Color.ALICEBLUE, // outlineWidth: 2 // } // }); // console.log("实体数量 = " + self.entities.values.length + " 高度=" + heights[0]); // self.entities.add(pointEntity); // console.log("实体数量 = " + self.entities.values.length); var airWindowId = options.id; /* 判断该div是否存在 */ var objAirBubbleWindow = document.getElementById(airWindowId); if (objAirBubbleWindow == null) { /* 创建div */ objAirBubbleWindow = document.createElement('div'); objAirBubbleWindow.id = airWindowId; objAirBubbleWindow.setAttribute('tag', 'label'); //设置标识 为了在地图变化的时候能找到需要处理的Div objAirBubbleWindow.className = 'jt-tooltip-popup'; objAirBubbleWindow.onclick = function() { this.style.display = 'none'; } /* 加入到页面 */ document.body.append(objAirBubbleWindow); } objAirBubbleWindow.style.display = 'flex'; var contentHtml = ""; /* 具体内容 */ contentHtml += "
"; contentHtml += "" + options.title + ""; contentHtml += "
"; contentHtml += "" + options.state + ""; contentHtml += "" + options.area + ""; contentHtml += "
"; contentHtml += "
"; /* 竖线 */ contentHtml += "
"; /* 底部小圆圈 */ contentHtml += "
"; /* 赋值 */ objAirBubbleWindow.innerHTML = contentHtml; /* 赋值位置 */ objAirBubbleWindow.style.top = (screenPoint.y - objAirBubbleWindow .clientHeight) + 'px'; objAirBubbleWindow.style.left = (screenPoint.x - objAirBubbleWindow .clientWidth / 2) + 'px'; /* 存储地理位置 */ objAirBubbleWindow.setAttribute('location', options.lng + "," + options.lat + "," + heights[0]); } }); }, /** * 重置标签的位置 */ resetLabelLocation() { /* 获取符合要求的全部标签 */ var labels = document.querySelectorAll("div[tag = 'label']"); for (var i = 0; i < labels.length; i++) { var labelDom = labels[i]; if (labelDom.style.display != 'none') { /* 说明该标签处于显示状态 获取存储的位置信息*/ var location = labelDom.getAttribute('location'); var res = this.wgs84ToScreen({ lng: location.split(',')[0], lat: location.split(',')[1], alt: location.split(',')[2], }); labelDom.style.top = (res.y - labelDom.clientHeight) + 'px'; labelDom.style.left = (res.x - labelDom.clientWidth / 2) + 'px'; } } } }); /** * 设置纹理属性信息 */ Cesium.Material.PolylineTrailLinkType = 'PolylineTrailLink'; Cesium.Material.PolylineTrailLinkImage = "./img/colors1.png"; Cesium.Material.PolylineTrailLinkSource = "czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ czm_material material = czm_getDefaultMaterial(materialInput);\n\ vec2 st = materialInput.st;\n\ vec4 colorImage = texture2D(image, vec2(fract(-st.s - time), st.t));\n\ material.alpha = colorImage.a * color.a;\n\ material.diffuse = (colorImage.rgb+color.rgb)/2.0;\n\ return material;\n\ }"; /** * 将自定义纹理添加到纹理缓存中 */ Cesium.Material._materialCache.addMaterial(Cesium.Material.PolylineTrailLinkType, { fabric: { type: Cesium.Material.PolylineTrailLinkType, uniforms: { color: new Cesium.Color(1.0, 0.0, 0.0, 0.5), image: Cesium.Material.PolylineTrailLinkImage, time: 0 }, source: Cesium.Material.PolylineTrailLinkSource }, translucent: function(material) { return true; } });