123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- /* 引入Cesium */
- // import * as Cesium from 'Cesium';
- /**
- * Cesium 的各种定位方法汇总,只列出项目中经常使用的,如果不够灵活,可直接调用Cesium官方API,也很方便。
- * Cesium的定位从效果上包含两种:直接定位、飞行定位。在方法封装上,姑且将直接定位分类为zoomTo系列,飞行定位分类flyTo。
- * 定位的对象上包括:坐标点、矩形范围、entities、3dtiles、gltf、kml、geojson、影像、地形、geometry
- * Cesium的定位主要是使用Camera对象和Viewer对象,Viewer的定位zoomTo,flyTo等方法是较高级别的函数,可以定位到Entity、3dtiles、DataSource等添加到三维球上显示的实体,
- * Viewer的定位方法内部都是调用Camera的相关定位方法,针对不同的定位对象,通过一些列计算得出传入实体的合适定位范围和摄像机视角,然后定位,使用起来很方便。
- * Camera的flyTo、flyToBoundingSphere、lookat、setView等方法是较低级别函数,通过定位坐标和角度参数的传入,精细化控制定位视角,灵活。
- */
- class LocateUtil {
- /**
- * 默认初始化
- * @param {Object} viewer 三维场景
- */
- constructor(viewer) {
- if (!viewer) throw new Cesium.DeveloperError('no viewer object!');
- this._viewer = viewer;
- this._locationEntity = null;
- }
- }
- /**
- * 通用对外公开函数(坐标定位)
- */
- Object.assign(LocateUtil.prototype, /** @lends LocateUtil.prototype */ {
- /**
- * 飞行定位到一个笛卡尔空间直角坐标点位置
- * @param {Object} options 具有以下属性:
- * @param {Number} options.longitude 经度,以度为单位
- * @param {Number} options.latitude 纬度,以度为单位
- * @param {Number} [options.height=0.0] 椭球的高度,以米为单位
- * @param {Number} [options.heading=0.0] 指向,默认值0.0(北)
- * @param {Number} [options.pitch=-90] 俯仰角, 垂直向下。默认值-90(向下看)。俯仰,人如果在赤道上空,俯仰角为0可见地球。如果在北纬,俯仰角为负才能见地球
- * @param {Number} [options.range=0.0] 距目标点距离
- * @param {Number} [options.duration=3] 持续时间
- */
- flyToPoint: function(options) {
- return new Promise((resolve, reject) => {
- if (!Cesium.defined(options) || !Cesium.defined(options.longitude) || !Cesium.defined(options.latitude)) {
- throw new Cesium.DeveloperError("options.longitude and options.latitude are required.");
- }
- // 初始化参数默认值
- options.height = Cesium.defaultValue(options.height, 0);
- options.heading = Cesium.defaultValue(options.heading, 0);
- options.pitch = Cesium.defaultValue(options.pitch, -90);
- options.range = Cesium.defaultValue(options.range, 0.0);
- options.duration = Cesium.defaultValue(options.duration, 3);
- var boundingSphere = new Cesium.BoundingSphere(Cesium.Cartesian3.fromDegrees(options.longitude, options.latitude, options.height), 0.0);
- this._viewer.camera.flyToBoundingSphere(boundingSphere, {
- duration: options.duration,
- complete: function() {
- resolve(true);
- },
- offset: {
- heading: Cesium.Math.toRadians(options.heading),
- pitch: Cesium.Math.toRadians(options.pitch),
- range: options.range
- },
- });
- });
- },
- /**
- * @description 根据坐标飞行定位,支持点、线、面等
- * @param {Array} points 坐标集合 [[lng,lat],[lng,lat],......]
- * @param {String} type 定位类型 point multiplePoint polyline polygon
- * @param {Object} [options] 飞行的样式,具有以下属性:
- * @param {Number} [options.heading=0.0] 指向,默认值0.0(北)
- * @param {Number} [options.pitch=-90] 俯仰角, 垂直向下。默认值-90(向下看)。俯仰,人如果在赤道上空,俯仰角为0可见地球。如果在北纬,俯仰角为负才能见地球
- * @param {Number} [options.range=0.0] 距目标点距离
- * @param {Number} [options.duration=3] 持续时间
- */
- flyToEntityByPoints: function(points, type, options) {
- return new Promise((resolve, reject) => {
- let _self = this;
- options = options || {};
- if (points === undefined || points.length === undefined) {
- reject("输入的坐标集合异常!");
- return;
- }
- /* 转换坐标 */
- let pointsArray = points.map(point => {
- return Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2] || 0);
- });
- if (_self._locationEntity) {
- _self._viewer.entities.remove(_self._locationEntity);
- }
- /* 分别判断 */
- switch (type) {
- case "point":
- _self._locationEntity = _self._viewer.entities.add({
- position: pointsArray[0],
- point: {
- pixelSize: 1,
- },
- });
- break;
- case "polyline":
- if (pointsArray.length < 2) {
- reject("线对象定位,点数至少2个");
- } else {
- _self._locationEntity = _self._viewer.entities.add({
- polyline: {
- positions: pointsArray,
- clampToGround: true, //指定折线是否应该固定在地面上
- // material: new Cesium.Color.fromCssColorString("#ffffff00"),
- material: new Cesium.Color(255, 0, 0, 0.5),
- width: 1,
- }
- });
- }
- break;
- case "polygon":
- if (pointsArray.length < 3) {
- reject("面对象定位,点数至少3个");
- } else {
- _self._locationEntity = _self._viewer.entities.add({
- polygon: {
- hierarchy: {
- positions: pointsArray
- },
- // material: new Cesium.Color.fromCssColorString("#ffffff00"),
- material: new Cesium.Color(255, 0, 0, 0.5),
- outline: true,
- }
- });
- }
- break;
- default:
- reject("坐标异常!");
- break;
- }
- // 初始化参数默认值
- options.duration = Cesium.defaultValue(options.duration, 3);
- options.heading = Cesium.defaultValue(options.heading, 0);
- options.pitch = Cesium.defaultValue(options.pitch, -90);
- options.range = Cesium.defaultValue(options.range, 0.0);
- let flyPromise = _self._viewer.flyTo(_self._locationEntity, {
- duration: options.duration,
- offset: {
- heading: Cesium.Math.toRadians(options.heading),
- pitch: Cesium.Math.toRadians(options.pitch),
- range: options.range
- }
- });
- flyPromise.then(function(flag) {
- if (flag) {
- // _self._viewer.entities.remove(_self._locationEntity);
- resolve(_self._locationEntity);
- }
- });
- });
- },
- /**
- * @description 飞行定位到一个实体
- * @param {Object} entity
- * @param {Number} [options.heading=0.0] 指向,默认值0.0(北)
- * @param {Number} [options.pitch=-90] 俯仰角, 垂直向下。默认值-90(向下看)。俯仰,人如果在赤道上空,俯仰角为0可见地球。如果在北纬,俯仰角为负才能见地球
- * @param {Number} [options.range=0.0] 距目标点距离
- * @param {Number} [options.duration=3] 持续时间
- */
- flyToEntity: function(entity, options) {
- return new Promise((resolve, reject) => {
- let _self = this;
- options = options || {};
- if (_self._locationEntity) {
- _self._viewer.entities.remove(_self._locationEntity);
- }
- _self._locationEntity = entity;
- // 初始化参数默认值
- options.duration = Cesium.defaultValue(options.duration, 3);
- options.heading = Cesium.defaultValue(options.heading, 0);
- options.pitch = Cesium.defaultValue(options.pitch, -90);
- options.range = Cesium.defaultValue(options.range, 0.0);
- let flyPromise = _self._viewer.flyTo(_self._locationEntity, {
- duration: options.duration,
- offset: {
- heading: Cesium.Math.toRadians(options.heading),
- pitch: Cesium.Math.toRadians(options.pitch),
- range: options.range
- }
- });
- flyPromise.then(function(flag) {
- if (flag) {
- // _self._viewer.entities.remove(_self._locationEntity);
- resolve(_self._locationEntity);
- }
- });
- });
- },
- /**
- * 定位实景三维
- * @param {Object} tileset
- * @param {Object} [options] 飞行的样式,具有以下属性:
- * @param {Number} [options.heading=120] 指向,默认值0.0(北)
- * @param {Number} [options.pitch=-10] 俯仰角, 垂直向下。默认值-90(向下看)。俯仰,人如果在赤道上空,俯仰角为0可见地球。如果在北纬,俯仰角为负才能见地球
- * @param {Number} [options.range=450.0] 距目标点距离
- * @param {Number} [options.duration=3] 持续时间
- */
- zoomToTilesets(tileset, options) {
- return new Promise((resolve, reject) => {
- let _self = this;
- if (!Cesium.defined(tileset)) {
- throw new Cesium.DeveloperError("tileset is required.");
- }
- // 初始化参数默认值
- options = options || {};
- options.heading = Cesium.defaultValue(options.heading, 120);
- options.pitch = Cesium.defaultValue(options.pitch, -10);
- options.range = Cesium.defaultValue(options.range, 450.0);
- options.duration = Cesium.defaultValue(options.duration, 3);
- // var boundingSphere = new Cesium.BoundingSphere(Cesium.Cartesian3.fromDegrees(options.longitude, options.latitude, options.height), 0.0);
- let boundingSphere = tileset.boundingSphere;
- _self._viewer.camera.flyToBoundingSphere(boundingSphere, {
- duration: options.duration,
- complete: function() {
- resolve(true);
- },
- offset: {
- heading: Cesium.Math.toRadians(options.heading),
- pitch: Cesium.Math.toRadians(options.pitch),
- range: options.range
- },
- });
- });
- },
- /**
- * 飞行定位实景三维
- * @param {Object} tileset
- * @param {Object} [options] 飞行的样式,具有以下属性:
- * @param {Number} [options.heading=120] 指向,默认值0.0(北)
- * @param {Number} [options.pitch=-10] 俯仰角, 垂直向下。默认值-90(向下看)。俯仰,人如果在赤道上空,俯仰角为0可见地球。如果在北纬,俯仰角为负才能见地球
- * @param {Number} [options.range=450.0] 距目标点距离
- * @param {Number} [options.duration=3] 持续时间
- */
- flyToTileset(tileset, options) {
- return new Promise((resolve, reject) => {
- let _self = this;
- if (!Cesium.defined(tileset)) {
- throw new Cesium.DeveloperError("tileset is required.");
- }
- // 初始化参数默认值
- options = options || {};
- options.heading = Cesium.defaultValue(options.heading, 120);
- options.pitch = Cesium.defaultValue(options.pitch, -10);
- options.range = Cesium.defaultValue(options.range, 450.0);
- options.duration = Cesium.defaultValue(options.duration, 3);
- /*viewer.flyTo() 方法,返回一个 promise (承诺)。
- * 如果飞行成功,该承诺将解析为 true;
- * 如果视图中目标不可见或飞行被取消,该承诺将解析为 false。
- * 用途:在飞到某实体后,移除该实体。*/
- let flyPromise = _self._viewer.flyTo(tileset, {
- duration: options.duration,
- offset: {
- heading: Cesium.Math.toRadians(options.heading),
- pitch: Cesium.Math.toRadians(options.pitch),
- range: options.range
- }
- });
- flyPromise.then(function(flag) {
- if (flag) {
- resolve(true);
- }
- });
- });
- }
- });
- export default LocateUtil;
|