• 国际惯例效果先放前面,满足往下看不满足跳过。


应用场景,无人机或者卫星实时传回的影像,实时显示。一般传回来的图需要经过服务器处理,然后再提供给显示端。可以提供所示区域包围盒范围内的地图。蓝色所示区域

地图是在不断更新中的怎么能保证,加载到最新的地图了?暂时想的是,有新区域影像形成时,通过通信的方式告知需重新绘制地图。即重新加载图层,将前一个图层清除。

//删除指定图层
viewer.imageryLayers.remove(layer, destroy)
//加载指定图层
viewer.imageryLayers.addImageryProvider(layer)
  • 添加第一个图层
const l = new Cesium.ArcGisMapServerImageryProvider({url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",})viewer.imageryLayers.addImageryProvider(l)
  • 添加第二个图层并在中间挖一个矩形用于显示第一个图层
layer = viewer.imageryLayers.addImageryProvider(new Cesium.UrlTemplateImageryProvider({url: "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}"
}))
layer.alpha = 0.7;
layer.cutoutRectangle = Cesium.Rectangle.fromDegrees(103.759293, 31.098898,103.765995, 31.102884
);
  • 在侦动画检测中根据移动改变数据
let mat4: Cesium.Matrix4; let pos: Cesium.Matrix4
; (viewer as any).frameUpdate.addEventListener(() => {const travelingRectangle = layer.cutoutRectangle;
if (flags.moveNorth &&travelingRectangle.north + moveIncrement < Cesium.Math.PI_OVER_TWO
) {travelingRectangle.north += moveIncrement;travelingRectangle.south += moveIncrement;
}
if (flags.moveSouth &&travelingRectangle.south - moveIncrement > -Cesium.Math.PI_OVER_TWO
) {travelingRectangle.north -= moveIncrement;travelingRectangle.south -= moveIncrement;
}
if (flags.moveEast) {travelingRectangle.east += moveIncrement;travelingRectangle.west += moveIncrement;
}
if (flags.moveWest) {travelingRectangle.east -= moveIncrement;travelingRectangle.west -= moveIncrement;
}
const center = Cesium.Rectangle.center(travelingRectangle, new Cesium.Cartographic())
const car3 = viewer.scene.globe.ellipsoid.cartographicToCartesian(center)
mat4 = Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.headingPitchRollToFixedFrame(car3,hpRollForUAV,Cesium.Ellipsoid.WGS84,fixedFrameTransform),new Cesium.Cartesian3(0, 0, 3000),new Cesium.Matrix4
)
model.modelMatrix = mat4
const center1 = Cesium.Cartographic.clone(center)
center1.height = 3000
const pos1 = viewer.scene.globe.ellipsoid.cartographicToCartesian(center1)
let orientation = Cesium.Transforms.headingPitchRollQuaternion(pos1, hpRoll)
//@ts-ignore
planePrimitive.update(pos1, orientation)
// lookAt()
travelingRectangle.east = wrapLongitude(travelingRectangle.east);
travelingRectangle.west = wrapLongitude(travelingRectangle.west);
});

不断添加单一图片图层

  • 不断添加SingleTileImageryProvider图片
async function test3() {function sleep(ms: number) {return new Promise(resolve => setTimeout(resolve, ms));}let lat1 = 31.098747;let lng1 = 103.770218let index = 0for (let i = 0; i < 26; i++) {lat1 = 31.098747lng1 += 0.0002index = 0for (let j = 0; j < 16; j++) {lat1 += 0.0002await sleep(400); // 等待 17没毫秒var provider = new Cesium.SingleTileImageryProvider({url: `Map/pengzhou/${206612 + i}_0${88176 + index}.png`,rectangle: Cesium.Rectangle.fromDegrees(lng1 - 0.0001, lat1 - 0.0001, lng1 + 0.0001, lat1 + 0.0001)});index++const layer = viewer.imageryLayers.addImageryProvider(provider)layer.alpha = 0.0let alpha = 0viewer.imageryLayers.layerAdded.addEventListener(layer => {const fn = () => {if (alpha >= 1.0) returnalpha += 0.01layer.alpha = alpharequestAnimationFrame(fn)}fn()})}}
}

Frustum代码

import { Cartesian3, Property, Primitive, Viewer, PerspectiveFrustum, Math as CesiumMath, FrustumGeometry, VertexFormat, GeometryInstance,ColorGeometryInstanceAttribute, Color, PerInstanceColorAppearance,FrustumOutlineGeometry, Quaternion
} from 'cesium'
type FrustumOtion = {position: Cartesian3,orientation?: Property | Quaternion,fov?: number, //视场(FOV)的角度,单位为弧度。near?: number, //最近距离far?: number, //最远距离aspectRatio?: number, //截头体的宽度与高度的纵横比。xOffset?:number, //X偏离距离yOffset?:number //Y偏离距离
}
export class CreateFrustum{private position: Cartesian3private viewer: Viewerprivate orientation: Property | Quaternionprivate fov: numberprivate near: numberprivate far: numberprivate aspectRatio: numberprivate xOffset: numberprivate yOffset: numberprivate frustumPrimitive: Primitive | null = nullprivate outlinePrimitive: Primitive | null = nullconstructor(viewer: Viewer, options: FrustumOtion){this.viewer = viewerthis.position = options.position;this.orientation = options.orientation || Quaternion.IDENTITY;this.fov = options.fov || 30;this.near = options.near || 10;this.far = options.far || 100;this.aspectRatio = options.aspectRatio ||  viewer.scene.canvas.clientWidth / viewer.scene.canvas.clientHeight;this.xOffset = options.xOffset || 0this.yOffset = options.yOffset || 0this.add();}// 更新视锥体的姿态update(position: Cartesian3, orientation: Property){this.position = position;this.orientation = orientation;this.add();}// 创建视锥体和轮廓线add(){this.clear();this.addFrustum();this.addOutline();}// 清除视锥体和轮廓线clear(){this.clearFrustum();this.clearOutline();}// 清除视锥体clearFrustum(){if(this.frustumPrimitive){this.viewer.scene.primitives.remove(this.frustumPrimitive);this.frustumPrimitive = null;}}// 清除轮廓线clearOutline(){if(this.outlinePrimitive){this.viewer.scene.primitives.remove(this.outlinePrimitive);this.outlinePrimitive = null;}}// 创建视锥体addFrustum(){let frustum = new PerspectiveFrustum({// 查看的视场角,绕Z轴旋转,以弧度方式输入// fov: Cesium.Math.PI_OVER_THREE,fov: CesiumMath.toRadians(this.fov),// 视锥体的宽度/高度aspectRatio: this.aspectRatio,// 近面距视点的距离near: this.near,// 远面距视点的距离far: this.far,xOffset: this.xOffset,yOffset: this.yOffset,});let geometry = new FrustumGeometry({frustum: frustum,origin: this.position,orientation: (this.orientation as any),vertexFormat: VertexFormat.POSITION_ONLY,});let instance = new GeometryInstance({geometry: geometry,attributes: {color: ColorGeometryInstanceAttribute.fromColor(new Color(1.0, 0.0, 0.0, 0.1)),},});let primitive = new Primitive({geometryInstances: instance,appearance: new PerInstanceColorAppearance({closed: true,flat: true,}),asynchronous: false,});this.frustumPrimitive = this.viewer.scene.primitives.add(primitive);}// 创建轮廓线addOutline(){let frustum = new PerspectiveFrustum({// 查看的视场角度,绕Z轴旋转,以弧度方式输入// The angle of the field of view (FOV), in radians. // This angle will be used as the horizontal FOV if the width is greater than the height, otherwise it will be the vertical FOV.fov: CesiumMath.toRadians(this.fov),// 视锥体的宽度/高度aspectRatio: this.aspectRatio,// 近面距视点的距离near: this.near,// 远面距视点的距离far: this.far,xOffset: this.xOffset,yOffset: this.yOffset,});let geometry = new FrustumOutlineGeometry({frustum: frustum,origin: this.position,orientation: (this.orientation as any),//@ts-ignorevertexFormat: VertexFormat.POSITION_ONLY,});let instance = new GeometryInstance({geometry: geometry,attributes: {color: ColorGeometryInstanceAttribute.fromColor(new Color(1.0, 0.0, 0.0, 0.1)),},});let primitive = new Primitive({geometryInstances: instance,appearance: new PerInstanceColorAppearance({closed: true,flat: true,}),asynchronous: false,});this.outlinePrimitive = this.viewer.scene.primitives.add(primitive);}
}export default CreateFrustum;

完整代码

<template><Map @onViewerLoaded="onViewerLoaded" :options="options" /><div class="position-center-top"><p><a-button @click="clear">清除图片</a-button><a-button @click="test3">循环加载图片</a-button></p><p>lng:<a-input-number style="width: 200px;" v-model:value="lng" :min="-180" :step="0.0002" :max="180"@change="change" /></p><p>lat:<a-input-number style="width: 200px;" v-model:value="lat" :min="-90" :step="0.0002" :max="90"@change="change" /></p><p>alt:<a-input-number style="width: 200px;" v-model:value="alt" :min="0" :step="1" @change="change" /></p><p>heading:<a-slider v-model:value="heading" :min="0" :max="360" @change="change" /></p><p>pitch:<a-slider v-model:value="pitch" :min="0" :max="360" @change="change" /></p><p>roll:<a-slider v-model:value="roll" :min="0" :max="360" @change="change" /></p><p><a-button type="primary" @mousedown="mousedown('S')" @mouseup="mouseup('S')"><template #icon><DownOutlined /></template></a-button><a-button type="primary" @mousedown="mousedown('W')" @mouseup="mouseup('W')"><template #icon><UpOutlined /></template></a-button><a-button type="primary" @mousedown="mousedown('A')" @mouseup="mouseup('A')"><template #icon><LeftOutlined /></template></a-button><a-button type="primary" @mousedown="mousedown('D')" @mouseup="mouseup('D')"><template #icon><RightOutlined /></template></a-button></p></div>
</template>
<script lang="ts" setup>
import Map from "@/components/Cesium/lib/Map.vue";
import * as Cesium from "cesium";
import type { Option } from '@/components/Cesium/typing'
import Frustum from './Frustum'
import { ref } from 'vue'
import { DownOutlined, UpOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons-vue'
import LCesiumApi from "@lib/main";
//@ts-ignore
const options: Option = {// terrainProvider: Cesium.createWorldTerrain(),navigatorOptions: {show: true}
}
const flags = {moveEast: false,moveWest: false,moveNorth: false,moveSouth: false,
};
const lat = ref<number>(31.100891);
const lng = ref<number>(103.762644);
const alt = ref<number>(3000);
const heading = ref<number>(180);
const pitch = ref<number>(180);
const roll = ref<number>(0);
function mousedown(keyCode: string) {switch (keyCode) {case "W":flags["moveNorth"] = truereturn "moveNorth";case "S":flags["moveSouth"] = truereturncase "D":flags["moveEast"] = truereturncase "A":flags["moveWest"] = truereturn}
}
function mouseup(keyCode: string) {switch (keyCode) {case "W":flags["moveNorth"] = falsereturn "moveNorth";case "S":flags["moveSouth"] = falsereturncase "D":flags["moveEast"] = falsereturncase "A":flags["moveWest"] = falsereturn}
}
const change = (): void => {position = Cesium.Cartesian3.fromDegrees(lng.value, lat.value, alt.value)model.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position);hpRoll.heading = Cesium.Math.toRadians(heading.value);hpRoll.roll = Cesium.Math.toRadians(roll.value)hpRoll.pitch = Cesium.Math.toRadians(pitch.value)let orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpRoll)//@ts-ignoreplanePrimitive.update(position, orientation)
};
let viewer: Cesium.Viewer
let layer: Cesium.ImageryLayer
let model: Cesium.Model
let position = Cesium.Cartesian3.fromDegrees(103.762644, 31.100891, 3000)
let hpRoll = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(heading.value), Cesium.Math.toRadians(roll.value), Cesium.Math.toRadians(pitch.value));
let hpRollForUAV = new Cesium.HeadingPitchRoll();
let planePrimitive: Frustum
const fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator("north","west"
);
const onViewerLoaded = (Viewer: Cesium.Viewer) => {viewer = Viewerviewer.imageryLayers.removeAll()const l = new Cesium.ArcGisMapServerImageryProvider({url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",})viewer.imageryLayers.addImageryProvider(l)layer = viewer.imageryLayers.addImageryProvider(new Cesium.UrlTemplateImageryProvider({url: "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}"}))viewer.imageryLayers.layerAdded.addEventListener(function(collection, index, layer1) {if (layer1 === layer) {// 图层加载完成后执行的代码console.log('图层加载完成');}});let p = new LCesiumApi.GetPosition(viewer)p.getPositionByClick((e: any) => {console.log(e)const ellipsoid = viewer.scene.globe.ellipsoid;const cartographic = ellipsoid.cartesianToCartographic(viewer.camera.position);const longitude = Cesium.Math.toDegrees(cartographic.longitude);const latitude = Cesium.Math.toDegrees(cartographic.latitude);const height = cartographic.height;console.log(longitude, latitude, height)// viewer.camera.position = Cesium.Cartesian3.fromDegrees(e.lng, e.lat, e.carmeraAlt)// console.log(viewer.camera.position)})layer.alpha = 0.7;viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(103.759293, 31.098898, 5000),complete: () => {loadModel()}})
}
function loadModel() {model = Cesium.Model.fromGltf({url: 'models/Drone.glb',scale: 10,id: 'UAV',modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(position,hpRollForUAV,Cesium.Ellipsoid.WGS84,fixedFrameTransform),})model.readyPromise.then(() => {test2()model.activeAnimations.addAll({multiplier: 0.5,loop: Cesium.ModelAnimationLoop.REPEAT,});})viewer.scene.primitives.add(model)const heading1 = Cesium.Math.toRadians(heading.value);const pitch1 = Cesium.Math.toRadians(pitch.value);const roll1 = Cesium.Math.toRadians(roll.value);const hpr = new Cesium.HeadingPitchRoll(heading1, pitch1, roll1);planePrimitive = new Frustum(viewer, {position: position,far: 2900,near: 0,fov: 12,aspectRatio: 1.5,orientation: Cesium.Transforms.headingPitchRollQuaternion(position,hpr)})
}
const lookAt = () => {const center = Cesium.Matrix4.multiplyByPoint(model.modelMatrix, model.boundingSphere.center, new Cesium.Cartesian3());//保存当前相机位置// const position = Cesium.Cartesian3.clone(viewer.camera.position);// const direction = Cesium.Cartesian3.clone(viewer.camera.direction);// const up = Cesium.Cartesian3.clone(viewer.camera.up);// //设置当前相机位置定位到模型处viewer.camera.lookAt(center, new Cesium.Cartesian3(0, 0, 1000));//在还原相机位置// Cesium.Cartesian3.clone(position, viewer.camera.position);// Cesium.Cartesian3.clone(direction, viewer.camera.direction);// Cesium.Cartesian3.clone(up, viewer.camera.up);// Cesium.Cartesian3.cross(direction, up, viewer.camera.right);
}
function test2() {const moveIncrement = 0.000001;function wrapLongitude(value: number) {if (value < -Cesium.Math.PI) {return value + Cesium.Math.TWO_PI;}if (value > Cesium.Math.PI) {return value - Cesium.Math.TWO_PI;}return value;}layer.cutoutRectangle = Cesium.Rectangle.fromDegrees(103.759293, 31.098898,103.765995, 31.102884);let mat4: Cesium.Matrix4; let pos: Cesium.Matrix4; (viewer as any).frameUpdate.addEventListener(() => {const travelingRectangle = layer.cutoutRectangle;if (flags.moveNorth &&travelingRectangle.north + moveIncrement < Cesium.Math.PI_OVER_TWO) {travelingRectangle.north += moveIncrement;travelingRectangle.south += moveIncrement;}if (flags.moveSouth &&travelingRectangle.south - moveIncrement > -Cesium.Math.PI_OVER_TWO) {travelingRectangle.north -= moveIncrement;travelingRectangle.south -= moveIncrement;}if (flags.moveEast) {travelingRectangle.east += moveIncrement;travelingRectangle.west += moveIncrement;}if (flags.moveWest) {travelingRectangle.east -= moveIncrement;travelingRectangle.west -= moveIncrement;}const center = Cesium.Rectangle.center(travelingRectangle, new Cesium.Cartographic())const car3 = viewer.scene.globe.ellipsoid.cartographicToCartesian(center)mat4 = Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.headingPitchRollToFixedFrame(car3,hpRollForUAV,Cesium.Ellipsoid.WGS84,fixedFrameTransform),new Cesium.Cartesian3(0, 0, 3000),new Cesium.Matrix4)model.modelMatrix = mat4const center1 = Cesium.Cartographic.clone(center)center1.height = 3000const pos1 = viewer.scene.globe.ellipsoid.cartographicToCartesian(center1)let orientation = Cesium.Transforms.headingPitchRollQuaternion(pos1, hpRoll)//@ts-ignoreplanePrimitive.update(pos1, orientation)// lookAt()travelingRectangle.east = wrapLongitude(travelingRectangle.east);travelingRectangle.west = wrapLongitude(travelingRectangle.west);});
}
async function test3() {function sleep(ms: number) {return new Promise(resolve => setTimeout(resolve, ms));}let lat1 = 31.098747;let lng1 = 103.770218let index = 0for (let i = 0; i < 26; i++) {lat1 = 31.098747lng1 += 0.0002index = 0for (let j = 0; j < 16; j++) {lat1 += 0.0002await sleep(400); // 等待 17没毫秒var provider = new Cesium.SingleTileImageryProvider({url: `Map/pengzhou/${206612 + i}_0${88176 + index}.png`,rectangle: Cesium.Rectangle.fromDegrees(lng1 - 0.0001, lat1 - 0.0001, lng1 + 0.0001, lat1 + 0.0001)});index++const layer = viewer.imageryLayers.addImageryProvider(provider)layer.alpha = 0.0let alpha = 0viewer.imageryLayers.layerAdded.addEventListener(layer => {const fn = () => {if (alpha >= 1.0) returnalpha += 0.01layer.alpha = alpharequestAnimationFrame(fn)}fn()})}}
}
function clear() {// primitives.removeAll()let a = viewer.imageryLayers.get(0) as any as Cesium.ImageryProviderlet b = viewer.imageryLayers.get(1) as any as Cesium.ImageryProviderviewer.imageryLayers.removeAll()viewer.imageryLayers.addImageryProvider(a)viewer.imageryLayers.addImageryProvider(b)}
</script>
<style scoped>
p {color: #fff;
}
</style>

cesium 实时地图叠加,实时影像回传绘制相关推荐

  1. Android 高德地图 Polyline 实时绘制行动轨迹

    前言 项目需求,需要做一个绘制行动轨迹的功能,因为本身项目集成的是高德地图,所以在此处,就针对高德地图来简单说一下绘制行动轨迹的功能. 使用到的功能 显示地图 定位 轨迹 实时位置信息存储 说明 实现 ...

  2. Lyft推出一种新的实时地图匹配算法

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 打车有时也会职业病发作,琢磨一下车辆调度是怎么做的,路径规划算法要怎么写,GPS偏移该怎么纠正等等.不 ...

  3. Python:利用python编程将上海十六区,2020年5月份房价实时地图(数据来源房天下)进行柱状图、热图可视化

    Python:利用python编程将上海十六区,2020年5月份房价实时地图(数据来源房天下)进行柱状图.热图可视化 目录 上海十六区,2020年5月份房价实时地图(数据来源房天下)可视化 雷达图.柱 ...

  4. postgres+socket.io+nodejs实时地图应用实践

    2019独角兽企业重金招聘Python工程师标准>>> nodejs一直以异步io著称,其语言特性尤其擅长于在realtime应用中,如聊天室等.在进行实时应用开发时,必不可少的需要 ...

  5. 【Baidu Apollo】基于人工驾驶路径的实时地图生成

    Apollo相对地图 基于人工驾驶路径的实时地图生成 百度资深软件工程师 Yifei Jiang   本文转自百度开发者社区 相对地图是在Apollo 2.5的时候第一次对外开放.在3.0的时候我们和 ...

  6. 中国区域地图叠加绘制

    中国区域地图叠加绘制 1.数据准备 2.相关Matlab代码及使用方法 3.图片固定位置信息标注 drawmap更新 1.数据准备   地理信息地图在进行绘制的过程中,叠加上行政区域,更方便进行位置定 ...

  7. 卡巴斯基网络威胁实时地图链接(装逼或学习)。

    卡巴斯基网络威胁实时地图(可用于学习). https://cybermap.kaspersky.com/cn/

  8. grafana的实时地图(学习笔记)

    我用到的数据是广东省汕头市的公交数据,那么说到地图我们就必然需要经纬度. 我这里是用到了grafana里面的MySQL数据源,所以里面的代码就全部用MySQL语句来实现 我这里用到了substring ...

  9. 安卓实现发送实时地图

    在多数即时聊天通讯中,会有发送位置的功能,在发送位置时,大家有注意的话,聊天界面的item里显示的是实时地图,如下图: 这个是如何实现的呢? 其实,这个很简单了,各大地图提供商都会有一个静态地图的AP ...

最新文章

  1. Java-Web 编码和路径
  2. gridview不换行,高亮显示
  3. tf.div()除法运算
  4. 理解CapsuleNetwork2
  5. Shutter - 带有众多功能的屏幕截图工具
  6. 1分钟玩转Kafka
  7. 实现一个行内三个div等分_css 实现等分布局
  8. new,malloc,GlobalAlloc详解
  9. 果真A站完了是B站,B站后台工程源码疑似泄露,已被GitHub删除!
  10. 按键精灵手机助手学习笔记
  11. 虚拟机查看HWADDR(即MAC)地址
  12. 股市前复权、后复权与不复权
  13. 深度学习之空洞卷积(Dilated/Atrous Convolution)
  14. fs.readFileSync 引入路径错误
  15. uniapp开发微信公众号网页-微信JSSDK使用
  16. VC中窗口在屏幕中央显示
  17. 高德地图——地图渲染及关键字搜索POI功能vue2/web端
  18. 面试官问:颜色转换 'rgb(255, 255, 255)' - '#FFFFFF' 的多种思路
  19. Python 中的 *list
  20. libjpeg用法linux压缩,libjpeg学习1:简单使用示例

热门文章

  1. ohmyzsh 更换主题
  2. 2019年人工智能的薪资前景如何?程序员如何学习人工智能?
  3. Vue · Vux:Tabbar导航
  4. 米尔科技zynq利用MIO操作LED灯的linux驱动
  5. LimeSDR 中文教程 (六)
  6. 开关电源PCB排版基本规则
  7. 如何在win10或win7下安装和运行debug
  8. Cocos Creator 骨骼动画 (龙骨DragonBones)
  9. SpringSecurity系列 之 AuthenticationEntryPoint接口及其实现类的用法
  10. 年轻时不做会后悔的八件事