3 files modified
2 files added
| New file |
| | |
| | | <svg width="44" height="44" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><filter x="-16.7%" y="-16.7%" width="133.3%" height="133.3%" filterUnits="objectBoundingBox" id="a"><feOffset in="SourceAlpha" result="shadowOffsetOuter1"/><feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0" in="shadowBlurOuter1"/></filter><circle id="b" cx="20" cy="18" r="18"/><path d="m14.717 10.35.212.016.425.022c.283.018.564.052.836.157.07.026.14.044.213.063.428.11.858.201 1.275.333.302.096.589.239.88.364.246.106.5.198.733.334.42.25.84.502 1.226.796.46.349.862.767 1.142 1.28.353.65.46 1.322.187 2.041-.331.877-.957 1.497-1.708 2.004-.413.279-.858.517-1.308.734a13.52 13.52 0 0 1-1.473.609c-.427.147-.873.246-1.31.345-.461.103-.925.194-1.39.26-.655.092-1.31.18-1.97.228a24.459 24.459 0 0 1-4.577-.096 20.238 20.238 0 0 1-2.475-.455c-.622-.15-1.226-.385-1.823-.612-.43-.166-.858-.356-1.263-.58-.899-.5-1.712-1.112-2.217-2.033-.328-.602-.442-1.24-.21-1.927.228-.682.656-1.214 1.204-1.651a13.85 13.85 0 0 1 1.282-.877c.232-.143.497-.235.748-.342.309-.132.618-.264.931-.377a7.7 7.7 0 0 1 .855-.272c.475-.117.953-.217 1.436-.305.195-.036.405-.033.604-.018.077.007.15.095.225.147-.052.066-.093.154-.159.198-.092.055-.206.08-.313.106-.387.096-.777.173-1.156.29-.38.118-.748.268-1.112.419-.243.099-.487.205-.711.337-.858.507-1.628 1.101-1.915 2.121-.077.28-.063.554.015.833.162.58.511 1.035.953 1.428a5.42 5.42 0 0 0 1.628 1.009c.556.216 1.112.448 1.687.616.486.147.99.235 1.491.32 1.046.172 2.1.29 3.204.235 1.123.077 2.269-.096 3.407-.268.512-.077 1.012-.239 1.513-.378.354-.1.707-.202 1.046-.345.961-.4 1.864-.903 2.527-1.74a2.31 2.31 0 0 0 .482-1.093c.092-.613-.162-1.123-.53-1.59-.313-.4-.722-.685-1.146-.96-.57-.379-1.204-.624-1.837-.86-.398-.15-.825-.227-1.238-.337l-.392-.1a2.662 2.662 0 0 1-.193-.061c-.07-.026-.118-.118-.177-.18.081-.066.166-.195.236-.187zm-.178 1.525c.226.004.379.122.435.326.113.407.214.815.33 1.219.134.463.275.926.416 1.389.093.315.201.626.278.94.016.06-.065.164-.133.208-.065.041-.17.03-.254.034-.665.003-1.33.007-1.994.007-.323 0-.403-.078-.415-.374-.017-.445-.037-.89-.057-1.334-.012-.24-.1-.318-.363-.318-1.12-.004-2.24-.004-3.364 0-.27 0-.383.089-.415.333-.056.452-.109.908-.157 1.363-.024.238-.097.326-.363.326-.737.008-1.479.008-2.216 0-.262-.003-.314-.118-.23-.344.141-.393.266-.79.383-1.186.214-.733.411-1.467.617-2.2.076-.278.241-.393.548-.393h1.208c.307 0 .395.078.383.367-.008.178-.036.356-.048.533-.016.27.076.36.366.36h1.532v.022h1.551c.342 0 .447-.104.423-.419-.012-.177-.04-.355-.044-.533-.004-.226.076-.315.314-.322.423-.011.846-.015 1.27-.004zm-4.783-1.9c.452.003.895.003 1.334.003h1.507c.238 0 .298.06.29.274-.004.104-.004.212-.008.315-.008.226-.105.323-.35.348-.053.004-.11.004-.162.004H9.752c-.39 0-.515-.115-.515-.474 0-.47 0-.47.52-.47zM12.585 8c.254 0 .31.056.306.282-.004.251 0 .503-.008.759-.004.215-.076.267-.31.267H9.595c-.294 0-.354-.052-.354-.323l-.004-.722c0-.207.056-.26.29-.263l.777.001.774-.001h1.507zM11.141.032c.254.319.504.642.747.972.637.859 1.27 1.721 1.908 2.58l1.002 1.358c.03.04.051.084.07.128.095.231-.004.393-.254.396-.509.008-1.02.004-1.529.004-.346 0-.38.033-.38.378 0 .503.005 1.002.008 1.505 0 .216-.051.271-.269.275-.464 0-.928-.004-1.395-.004H9.668c-.24 0-.288-.055-.288-.293.004-.507.004-1.017.004-1.523 0-.301-.044-.338-.339-.338-.504.004-1.005.011-1.51-.004-.103-.003-.272-.058-.29-.12a.474.474 0 0 1 .058-.368c.73-1.005 1.473-2 2.21-2.998.42-.572.836-1.145 1.256-1.717.066-.088.129-.18.21-.25.03-.025.136-.01.162.019z" id="c"/></defs><g fill="none" fill-rule="evenodd"><g transform="translate(2 4)"><use fill="#000" filter="url(#a)" xlink:href="#b"/><use fill="#2D8CF0" xlink:href="#b"/></g><g transform="translate(11 11.624)"><mask id="d" fill="#fff"><use xlink:href="#c"/></mask><use fill="#000" fill-rule="nonzero" xlink:href="#c"/><g mask="url(#d)"><path fill="#FFF" d="M-22-26h68v68h-68z"/></g></g></g></svg> |
| | |
| | | subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'], |
| | | tilingScheme: new Cesium.GeographicTilingScheme(), |
| | | tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19'], |
| | | maximumLevel: 50, |
| | | maximumLevel: 17, |
| | | }) |
| | | // 标准地图图层变量 |
| | | const imageryProvider_stand = new Cesium.UrlTemplateImageryProvider({ |
| | |
| | | <a-input v-model:value="currentWayLine.name" placeholder="请输入航线名称" /> |
| | | </a-modal> |
| | | </div> |
| | | <!-- 航线编辑 --> |
| | | <ul class="targt-point scrollbar" :style="{ height: height + 'px' }" v-else> |
| | | <div class="back-btn" @click="isPointListOpen = !isPointListOpen"> |
| | | <div class="back-btn" @click="backPage"> |
| | | <ArrowLeftOutlined /> |
| | | <span>返回上一页</span> |
| | | </div> |
| | | <div class="wayline-info"> |
| | | <div class="info-box" v-for="(item, index) in waylineDetails" :key="index"> |
| | | <div class="title">{{ item.title }}</div> |
| | | <div class="info">{{ item.value }}</div> |
| | | </div> |
| | | </div> |
| | | <li v-for="(item, index) in tragetPointArr" :key="index" :class="{ selectedColor: index === selectedPoint }" |
| | | @click="tragetPointClick(item.position, index)"> |
| | |
| | | import { message } from 'ant-design-vue' |
| | | import { onMounted, onUpdated, ref } from 'vue' |
| | | import ImageTrailMaterial from '/@/utils/cesium/ImageTrailMaterial' |
| | | import { getPolylineLength } from '/@/utils/cesium/mapUtils' |
| | | import { |
| | | deleteWaylineFile, |
| | | downloadWaylineFile, |
| | |
| | | |
| | | const getResource = (name: string) => { |
| | | return new URL(`/src/assets/icons/${name}`, import.meta.url).href |
| | | } |
| | | const getResourceSvg = (name: string) => { |
| | | return new URL(`/src/assets/svg/${name}`, import.meta.url).href |
| | | } |
| | | |
| | | const projectWayLine = ref<HTMLDivElement>() |
| | |
| | | ) |
| | | const editVisible = ref<boolean>(false) |
| | | const height = ref() |
| | | const { removeById, addClickEvent, getEntityById, addPolyline } = cesiumOperation() |
| | | const { removeById, addClickEvent, getEntityById, addPolyline, removeAllPoint } = cesiumOperation() |
| | | |
| | | const isPointListOpen = ref<boolean>(false) |
| | | const tragetPointArr = ref< |
| | |
| | | if (kmlDataSource) { |
| | | global.$viewer.dataSources.remove(kmlDataSource) |
| | | } |
| | | removeById('entityLine') |
| | | removeById('bottomLine') |
| | | // removeById('entityLine') |
| | | removeAllPoint() |
| | | removeById('clickBox') |
| | | store.commit('SET_WAYLINE_INFO', { |
| | | isShow: false, |
| | |
| | | * @param file |
| | | */ |
| | | function initKmlFile (file: string) { |
| | | // const [, address] = file.split('cloud-bucket') |
| | | // file = import.meta.env.VITE_MEDIAPANEL_API_URL + address |
| | | removeById('entityLine') |
| | | removeById('bottomLine') |
| | | // removeById('entityLine') |
| | | removeAllPoint() |
| | | const options = { |
| | | camera: global.$viewer.scene.camera, |
| | | canvas: global.$viewer.scene.canvas, |
| | |
| | | .add(Cesium.KmlDataSource.load(file, options)) |
| | | .then((res: any) => { |
| | | kmlDataSource = res |
| | | kmlEntity.value = kmlDataSource.entities.values |
| | | kmlDataSource.show = true |
| | | const kmlEntityArr = kmlDataSource.entities.values[0]._children |
| | | const cartesianArr: any[] = [] |
| | | for (let i = 0; i < kmlEntityArr.length; i++) { |
| | | const entity = kmlEntityArr[i] |
| | | const billboard = createBillboard(`${i + 1}`, '#2D8CF0') |
| | | entity._id = 'tragetPoint' + i |
| | | entity.billboard = new Cesium.BillboardGraphics({ |
| | | image: billboard, |
| | | pixelOffset: new Cesium.Cartesian2(0, -20), |
| | | }) |
| | | entity.point = new Cesium.PointGraphics({ |
| | | pixelSize: 20, |
| | | color: Cesium.Color.GHOSTWHITE, |
| | | outlineColor: Cesium.Color.BLACK, |
| | | }) |
| | | cartesianArr.push(entity.position._value) |
| | | tragetPointArr.value[i] = { |
| | | position: entity.position._value, |
| | | eventList: [], |
| | | } |
| | | } |
| | | // tragetPointArr.value = cartesianArr |
| | | // const stripe = createStripe() |
| | | // 绘制静态线 |
| | | addPolyline({ |
| | | id: 'entityLine', |
| | | polyline: { |
| | | positions: cartesianArr, |
| | | width: 10, |
| | | material: new Cesium.ImageMaterialProperty({ |
| | | image: getResource('arrow-right.png'), |
| | | color: Cesium.Color.WHITE, |
| | | repeat: new Cesium.Cartesian2(30, 1), |
| | | }), |
| | | zIndex: 2, |
| | | clampToGround: true, // 关闭贴地效果,保留高度 |
| | | }, |
| | | }) |
| | | addPolyline({ |
| | | id: 'bottomLine', |
| | | polyline: { |
| | | positions: cartesianArr, |
| | | width: 7, |
| | | material: Cesium.Color.fromBytes(96, 210, 149), |
| | | zIndex: 1, |
| | | clampToGround: true, // 关闭贴地效果,保留高度 |
| | | }, |
| | | }) |
| | | |
| | | const lineEntity = getEntityById('entityLine') |
| | | global.$viewer.flyTo(lineEntity, { |
| | | offset: new Cesium.HeadingPitchRange(0, -90, 200), |
| | | }) |
| | | |
| | | createPointMarker(kmlDataSource) |
| | | // 解析kmz文件 |
| | | readKmzFile(file) |
| | | }) |
| | | } |
| | | |
| | | const waylineDetails = reactive([ |
| | | { |
| | | title: '航线长度', |
| | | value: '0' |
| | | }, |
| | | { |
| | | title: '预计执行时间', |
| | | value: '0' |
| | | }, |
| | | { |
| | | title: '航点', |
| | | value: 0 |
| | | }, |
| | | { |
| | | title: '照片', |
| | | value: 0 |
| | | }, |
| | | ]) |
| | | function createPointMarker (dataSource: { entities: { values: { _children: any }[] }; show: boolean }) { |
| | | const ellipsoid = global.$viewer.scene.globe.ellipsoid |
| | | kmlEntity.value = dataSource.entities.values |
| | | dataSource.show = true |
| | | const kmlEntityArr = dataSource.entities.values[0]._children |
| | | const cartesianArr: any[] = [] |
| | | let btmStartPoint = null |
| | | for (let i = 0; i < kmlEntityArr.length; i++) { |
| | | const entity = kmlEntityArr[i] |
| | | // 将cartographic3D坐标转换为正常坐标 |
| | | const c3Position = entity.position._value |
| | | const c2Postion = ellipsoid.cartesianToCartographic(c3Position) |
| | | const longitude = Cesium.Math.toDegrees(c2Postion.longitude) |
| | | const latitude = Cesium.Math.toDegrees(c2Postion.latitude) |
| | | const height = 100 |
| | | entity.position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height) |
| | | if (i === 0) { |
| | | btmStartPoint = Cesium.Cartesian3.fromDegrees(longitude, latitude, 0) |
| | | } |
| | | // 创建广告牌信息 |
| | | const billboard = createBillboard(`${i + 1}`, '#61d396') |
| | | // 修改id |
| | | entity._id = 'tragetPoint' + i |
| | | // 修改广告牌样式 |
| | | entity.billboard = new Cesium.BillboardGraphics({ |
| | | image: billboard, |
| | | pixelOffset: new Cesium.Cartesian2(0, -20), |
| | | }) |
| | | // 修改点的信息 |
| | | entity.point = new Cesium.PointGraphics({ |
| | | pixelSize: 20, |
| | | color: Cesium.Color.GHOSTWHITE, |
| | | outlineColor: Cesium.Color.BLACK, |
| | | }) |
| | | // 创建虚线 |
| | | addPolyline({ |
| | | id: 'dashLine' + i, |
| | | polyline: { |
| | | positions: Cesium.Cartesian3.fromDegreesArrayHeights([ |
| | | longitude, |
| | | latitude, |
| | | height, |
| | | longitude, |
| | | latitude, |
| | | 0 |
| | | ]), |
| | | width: 1, |
| | | material: new Cesium.PolylineDashMaterialProperty({ |
| | | color: Cesium.Color.WHITE |
| | | }) |
| | | } |
| | | }) |
| | | cartesianArr.push(entity.position._value) |
| | | tragetPointArr.value[i] = { |
| | | position: entity.position._value, |
| | | eventList: [], |
| | | } |
| | | } |
| | | // 创建起飞位置 |
| | | global.$viewer.entities.add({ |
| | | id: 'dronePosition', |
| | | position: btmStartPoint, |
| | | billboard: { |
| | | image: getResource('dock.png'), |
| | | width: 36, |
| | | height: 36, |
| | | } |
| | | }) |
| | | // 绘制链接线 |
| | | addPolyline({ |
| | | id: 'entityLine', |
| | | polyline: { |
| | | positions: [btmStartPoint, ...cartesianArr], |
| | | width: 7, |
| | | material: new ImageTrailMaterial({ |
| | | backgroundColor: Cesium.Color.fromBytes(96, 210, 149), |
| | | image: getResource('arrow-right.png'), |
| | | imageW: 7, |
| | | duration: 0, |
| | | animation: false |
| | | }), |
| | | clampToGround: false, // 关闭贴地效果,保留高度 |
| | | }, |
| | | }) |
| | | const lineEntity = getEntityById('entityLine') |
| | | const polylineLength = getPolylineLength(lineEntity).toFixed(1) || 0 |
| | | waylineDetails[0].value = polylineLength + 'm' |
| | | waylineDetails[2].value = cartesianArr.length |
| | | global.$viewer.flyTo(lineEntity, { |
| | | offset: new Cesium.HeadingPitchRange(0, -90, 300), |
| | | }) |
| | | } |
| | | |
| | | // 返回上一页 |
| | | function backPage () { |
| | | isPointListOpen.value = false |
| | | store.commit('SET_WAYLINE_INFO', { |
| | | isShow: false, |
| | | wayline: {}, |
| | | position: 0, |
| | | }) |
| | | } |
| | | |
| | | // 点击目标点 |
| | |
| | | selectedPoint.value = index |
| | | store.commit('SET_WAYLINE_INFO', { |
| | | isShow: true, |
| | | wayline: currentWayLine, |
| | | wayline: currentWayLine.value, |
| | | position: index, |
| | | }) |
| | | if (getEntityById('clickBox')) { |
| | |
| | | }) |
| | | } |
| | | ) |
| | | // 创建盒子 |
| | | const entity = { |
| | | id: 'clickBox', |
| | | position, |
| | | box: { |
| | | dimensions: new Cesium.Cartesian3(10.0, 10.0, 120), |
| | | material: Cesium.Color.MEDIUMSPRINGGREEN.withAlpha(0.1), |
| | | // outline: true, |
| | | // outlineColor: Cesium.Color.MEDIUMSPRINGGREEN.withAlpha(0.8), |
| | | heightReference: true, |
| | | }, |
| | | } |
| | | |
| | | const boxEntity = global.$viewer.entities.add(entity) |
| | | global.$viewer.flyTo(boxEntity, { |
| | | duration: 3, |
| | | }) |
| | | } |
| | | |
| | | function onScroll (e: any) { |
| | |
| | | } |
| | | |
| | | // 创建广告牌 |
| | | const createBillboard = (title: string, color: string) => { |
| | | const createBillboard = (title: string | number, color: string) => { |
| | | // 创建canvas绘制广告牌 |
| | | const billboard = document.createElement('canvas') |
| | | billboard.width = 30 |
| | |
| | | ctx.fill() |
| | | ctx.font = '18px serif' |
| | | ctx.fillStyle = '#ffffff' |
| | | ctx.fillText(title, 10, 15) |
| | | ctx.fillText(Number(title) === 1 ? 'S' : title, 10, 15) |
| | | ctx.closePath() |
| | | return billboard |
| | | } |
| | | |
| | | // 创建条纹 |
| | | const createStripe = () => { |
| | | // 创建canvas绘制广告牌 |
| | | const stripe = document.createElement('canvas') |
| | | stripe.width = 40 |
| | | stripe.height = 40 |
| | | const ctx: HTMLCanvasElement | any = stripe.getContext('2d') |
| | | ctx.beginPath() |
| | | ctx.moveTo(0, 20) |
| | | ctx.lineTo(0, 40) |
| | | ctx.lineTo(20, 20) |
| | | ctx.lineTo(20, 0) |
| | | ctx.fillStyle = '#fff' |
| | | ctx.fill() |
| | | ctx.closePath() |
| | | ctx.beginPath() |
| | | ctx.moveTo(20, 0) |
| | | ctx.lineTo(20, 20) |
| | | ctx.lineTo(40, 40) |
| | | ctx.lineTo(40, 20) |
| | | ctx.fillStyle = '#fff' |
| | | ctx.fill() |
| | | ctx.closePath() |
| | | return stripe |
| | | } |
| | | |
| | | /** |
| | |
| | | color: #2d8cf0; |
| | | } |
| | | } |
| | | .wayline-info { |
| | | display: flex; |
| | | height: 50px; |
| | | margin: 10px 0; |
| | | text-align: center; |
| | | align-items: center; |
| | | .info-box { |
| | | flex: 1; |
| | | border-right: 1px solid hsla(0,0%,100%,.1); |
| | | .title { |
| | | color: hsla(0,0%,100%,.65); |
| | | font-size: 12px; |
| | | font-weight: bold; |
| | | } |
| | | .info { |
| | | font-weight: bold; |
| | | } |
| | | &:last-child { |
| | | border: 0; |
| | | } |
| | | } |
| | | } |
| | | |
| | | li { |
| | | cursor: pointer; |
| | |
| | | background-color: #3c3c3c; |
| | | } |
| | | </style> |
| | | ../../../utils/cesium/polylineImageTrailMaterial |
| | |
| | | import * as Cesium from 'cesium' |
| | | /** |
| | | * 定义Cesium材质对象 |
| | | */ |
| | | class ImageTrailMaterial { |
| | | _definitionChanged: Cesium.Event<(...args: any[]) => void>; |
| | | _color: undefined; |
| | | _colorSubscription: undefined; |
| | | _speed: undefined; |
| | | _speedSubscription: undefined; |
| | | _image: undefined; |
| | | _imageSubscription: undefined; |
| | | _repeat: undefined; |
| | | _repeatSubscription: undefined; |
| | | color: any; |
| | | speed: any; |
| | | image: any; |
| | | repeat: Cesium.Cartesian2; |
| | | constructor (options : any = {}) { |
| | | this._definitionChanged = new Cesium.Event() |
| | | this._color = undefined |
| | | this._colorSubscription = undefined |
| | | this._speed = undefined |
| | | this._speedSubscription = undefined |
| | | this._image = undefined |
| | | this._imageSubscription = undefined |
| | | this._repeat = undefined |
| | | this._repeatSubscription = undefined |
| | | this.color = options.color || Cesium.Color.fromBytes(0, 0, 255, 255) |
| | | this.speed = options.speed || 1 |
| | | this.image = options.image |
| | | this.repeat = new Cesium.Cartesian2( |
| | | options.repeat?.x || 1, |
| | | options.repeat?.y || 1 |
| | | ) |
| | | } |
| | | import * as cesium from 'cesium' |
| | | |
| | | get isConstant () { |
| | | return false |
| | | } |
| | | const Cesium: any = cesium |
| | | |
| | | get definitionChanged () { |
| | | return this._definitionChanged |
| | | } |
| | | const getResource = (name: string) => { |
| | | return new URL(`/src/assets/icons/${name}`, import.meta.url).href |
| | | } |
| | | |
| | | getType () { |
| | | return Cesium.Material.ImageTrailMaterialType |
| | | } |
| | | const defaultColor = Cesium.Color.TRANSPARENT |
| | | const defaultImage = getResource('arrow-right.png') |
| | | const defaultImageimageW = 10 |
| | | const defaultAnimation = false |
| | | const defaultDuration = 3000 |
| | | |
| | | getValue (time: any, result: any) { |
| | | if (!result) { |
| | | result = {} |
| | | } |
| | | result.color = Cesium.Property?.getValueOrUndefined(this._color, time) |
| | | result.image = Cesium.Property?.getValueOrUndefined(this._image, time) |
| | | result.repeat = Cesium.Property?.getValueOrUndefined(this._repeat, time) |
| | | result.speed = this._speed |
| | | return result |
| | | } |
| | | function ImageTrailMaterial (this: any, opt: any = {}) { |
| | | opt = Cesium.defaultValue(opt, Cesium.defaultValue.EMPTY_OBJECT) |
| | | this._definitionChanged = new Cesium.Event() |
| | | // 自定义材质 |
| | | // 自定义图片颜色 |
| | | this._color = undefined |
| | | this._colorSubscription = undefined |
| | | // 自定义背景颜色 |
| | | this._backgroundColor = undefined |
| | | this._backgroundColorSubscription = undefined |
| | | // 图片 |
| | | this._image = undefined |
| | | this._imageSubscription = undefined |
| | | // 图片宽度 |
| | | this._imageW = undefined |
| | | this._imageWSubscription = undefined |
| | | // 是否开启动画 |
| | | this._animation = undefined |
| | | this._animationSubscription = undefined |
| | | // 动画持续时间 |
| | | this._duration = undefined |
| | | this._durationSubscription = undefined |
| | | |
| | | equals (other: this) { |
| | | return ( |
| | | this === other || |
| | | (other instanceof ImageTrailMaterial && |
| | | Cesium.Property.equals(this._color, other._color) && |
| | | Cesium.Property.equals(this._image, other._image) && |
| | | Cesium.Property.equals(this._repeat, other._repeat) && |
| | | Cesium.Property.equals(this._speed, other._speed)) |
| | | ) |
| | | // 变量初始化 |
| | | this.color = opt.color || defaultColor // 颜色 |
| | | this.backgroundColor = opt.backgroundColor || defaultColor // 颜色 |
| | | this._image = opt.image || defaultImage // 材质图片 |
| | | this.imageW = opt.imageW || defaultImageimageW |
| | | this.animation = opt.animation || defaultAnimation |
| | | this.duration = opt.duration || defaultDuration |
| | | this._time = undefined |
| | | } |
| | | |
| | | ImageTrailMaterial.prototype.getType = function () { |
| | | return Cesium.Material.ImageTrailMaterialType |
| | | } |
| | | |
| | | // 这个方法在每次渲染时被调用,result的参数会传入glsl中。 |
| | | ImageTrailMaterial.prototype.getValue = function ( |
| | | time: any, |
| | | result: { |
| | | color?: any |
| | | backgroundColor?: any |
| | | image?: any |
| | | imageW?: any |
| | | animation?: any |
| | | time?: any |
| | | }, |
| | | ) { |
| | | if (!Cesium.defined(result)) { |
| | | result = {} |
| | | } |
| | | // result.color = Cesium.Property.getValueOrClonedDefault( |
| | | // this._color, |
| | | // time, |
| | | // defaultColor, |
| | | // result.color, |
| | | // ) |
| | | // result.backgroundColor = Cesium.Property.getValueOrClonedDefault( |
| | | // this._backgroundColor, |
| | | // time, |
| | | // defaultColor, |
| | | // result.backgroundColor, |
| | | // ) |
| | | result.color = Cesium.Property.getValueOrUndefined(this._color, time) |
| | | result.backgroundColor = Cesium.Property.getValueOrUndefined(this._backgroundColor, time) |
| | | result.image = this._image |
| | | result.imageW = this._imageW |
| | | result.animation = this._animation |
| | | if (this._time === undefined) { |
| | | this._time = new Date().getTime() |
| | | } |
| | | result.time = |
| | | ((new Date().getTime() - this._time) % this._duration) / this._duration |
| | | return result |
| | | } |
| | | |
| | | ImageTrailMaterial.prototype.equals = function (other: { |
| | | _color: any |
| | | _backgroundColor: any |
| | | }) { |
| | | return ( |
| | | this === other || |
| | | (other instanceof ImageTrailMaterial && |
| | | Cesium.Property.equals(this._color, other._color) && |
| | | Cesium.Property.equals(this._backgroundColor, other._backgroundColor)) |
| | | ) |
| | | } |
| | | |
| | | Object.defineProperties(ImageTrailMaterial.prototype, { |
| | | isConstant: { |
| | | get: function get () { |
| | | return false |
| | | }, |
| | | }, |
| | | definitionChanged: { |
| | | get: function get () { |
| | | return this._definitionChanged |
| | | }, |
| | | }, |
| | | color: Cesium.createPropertyDescriptor('color'), |
| | | speed: Cesium.createPropertyDescriptor('speed'), |
| | | backgroundColor: Cesium.createPropertyDescriptor('backgroundColor'), |
| | | image: Cesium.createPropertyDescriptor('image'), |
| | | repeat: Cesium.createPropertyDescriptor('repeat'), |
| | | imageW: Cesium.createPropertyDescriptor('imageW'), |
| | | animation: Cesium.createPropertyDescriptor('animation'), |
| | | duration: Cesium.createPropertyDescriptor('duration'), |
| | | }) |
| | | // 材质类型 |
| | | Cesium.Material.ImageTrailMaterialType = 'PolylineImageTrail' |
| | | // 添加材质到缓冲区中 |
| | | Cesium.Material._materialCache.addMaterial( |
| | | Cesium.Material.ImageTrailMaterialType, |
| | | { |
| | | fabric: { |
| | | type: Cesium.Material.ImageTrailMaterialType, |
| | | // uniform变量 |
| | | uniforms: { |
| | | color: new Cesium.Color(1.0, 0.0, 0.0, 0.7), |
| | | image: Cesium.Material.DefaultImageId, |
| | | speed: 1, |
| | | repeat: new Cesium.Cartesian2(1, 1), |
| | | }, |
| | | // |
| | | source: ` |
| | | uniform sampler2D image; |
| | | uniform float speed; |
| | | uniform vec4 color; |
| | | uniform vec2 repeat; |
| | | |
| | | czm_material czm_getMaterial(czm_materialInput materialInput){ |
| | | czm_material material=czm_getDefaultMaterial(materialInput); |
| | | vec2 st=repeat * materialInput.st; |
| | | float time=fract(czm_frameNumber*speed/1000.); |
| | | // st.s是横轴方向运动,st.t是纵轴, |
| | | // vec2(fract(st.s-time),st.t)是横轴按照时间变化而变化,纵轴保持正常不变化 |
| | | vec4 colorImage=texture2D(image,vec2(fract(st.s-time),st.t)); |
| | | vec4 fragColor; |
| | | fragColor.rgb=color.rgb / 1.0; |
| | | if(color.a==0.){ |
| | | material.alpha=colorImage.a; |
| | | material.diffuse=colorImage.rgb; |
| | | }else{ |
| | | material.alpha=colorImage.a*color.a; |
| | | material.diffuse=max(color.rgb*material.alpha*3.,color.rgb); |
| | | } |
| | | return material; |
| | | } |
| | | ` |
| | | }, |
| | | translucent: function () { |
| | | return true |
| | | }, |
| | | } |
| | | ) |
| | | |
| | | export default ImageTrailMaterial |
| | | // 写到Cesium对象上,就可以像其他MaterialProperty一样使用了 |
| | | Cesium.Material.ImageTrailMaterialType = 'PolylineImageTrail' |
| | | |
| | | Cesium.Material._materialCache.addMaterial(Cesium.Material.ImageTrailMaterialType, { |
| | | fabric: { |
| | | type: 'ImageLine', |
| | | uniforms: { |
| | | // uniforms参数跟我们上面定义的参数以及getValue方法中返回的result对应,这里值是默认值 |
| | | color: new Cesium.Color(1, 0, 0, 1.0), |
| | | backgroundColor: new Cesium.Color(0, 0, 0, 0.0), |
| | | image: '', |
| | | imageW: 1, |
| | | animation: false, |
| | | duration: 30, |
| | | time: 0, |
| | | }, |
| | | // source编写glsl,可以使用uniforms参数,值来自getValue方法的result |
| | | source: ` |
| | | czm_material czm_getMaterial(czm_materialInput materialInput) |
| | | { |
| | | czm_material material = czm_getDefaultMaterial(materialInput); |
| | | vec2 st = materialInput.st; |
| | | float s = st.s/ (abs(fwidth(st.s)) * imageW * czm_pixelRatio); |
| | | if(animation==true){ |
| | | s = s-time;//增加运动效果 |
| | | } |
| | | float t = st.t; |
| | | vec4 colorImage = texture(image, vec2(fract(s), t)); |
| | | material.diffuse = colorImage.rgb; |
| | | material.emission = max(backgroundColor.rgb*material.alpha*1.,backgroundColor.rgb); |
| | | return material; |
| | | } |
| | | `, |
| | | }, |
| | | translucent: function translucent () { |
| | | return true |
| | | }, |
| | | }) |
| | | |
| | | export default (ImageTrailMaterial as any) |
| New file |
| | |
| | | import * as Cesium from 'cesium' |
| | | |
| | | export function getLngLatDistance ( |
| | | lat1: number, |
| | | lng1: number, |
| | | lat2: number, |
| | | lng2: number, |
| | | ) { |
| | | const radLat1 = (lat1 * Math.PI) / 180.0 |
| | | const radLat2 = (lat2 * Math.PI) / 180.0 |
| | | const a = radLat1 - radLat2 |
| | | const b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0 |
| | | let s = |
| | | 2 * |
| | | Math.asin( |
| | | Math.sqrt( |
| | | Math.pow(Math.sin(a / 2), 2) + |
| | | Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2), |
| | | ), |
| | | ) |
| | | s = s * 6378.137 // EARTH_RADIUS; |
| | | s = Math.round(s * 10000) / 10000 |
| | | return s * 1000 |
| | | } |
| | | |
| | | export function getPolylineLength (entity: any) { |
| | | let length = 0 |
| | | |
| | | // 获取Polyline的所有顶点位置 |
| | | const positions = entity.polyline.positions.getValue() |
| | | |
| | | for (let i = 0; i < positions.length - 1; ++i) { |
| | | const startPosition = positions[i] |
| | | const endPosition = positions[i + 1] |
| | | |
| | | // 使用Cesium提供的distanceBetween函数计算两个顶点之间的距离 |
| | | const distance = Cesium.Cartesian3.distance(startPosition, endPosition) |
| | | |
| | | // 将每个顶点之间的距离相加得到总长度 |
| | | length += distance |
| | | } |
| | | |
| | | return length |
| | | } |