数字孪生-DTS-孪创城市-低空范围

前言

今天蘑菇头带来的是低空范围的功能实现分享,主要是当点击低空范围时会显示出所有的图层,包括限飞范围,申请范围和无人机平台,并且我们还做了一个图层控制的按钮,可以很方便的控制着三个图层的显示和隐藏,并且还做了相应的图例,快来看看是如何实现的吧。

思路

首先还是老样子,需要调整视角,设置暗黑模式这里我就不赘述了,直接看代码。

javascript 复制代码
import { useDigitalTwinStore } from '@/stores/digitalTwin'
import { getForbidFlyRegion, getLimitFlyRegion, getApplyCoverage, getPlatformData } from '@/api/home'
const digitalTwinStore = useDigitalTwinStore()

const cameraParam = [554876.14875, 3386383.881719, 104995.88, -54.943035, -89.999977, 2]
const hideLayer = ['手工模型', 'cim2建筑', '苏州地形影像_Water']
const setStyles = async () => {
    //样式调整:a.打开黑暗模式  b.隐藏手工模型  c.调整地形影像的亮度
    await fdapi.camera.set(cameraParam)
    await fdapi.weather.setDarkMode(true)
    await fdapi.infoTree.hide(hideLayer.map(name => digitalTwinStore.digitalTwin[name]))
    await fdapi.tileLayer.setStyle(digitalTwinStore.digitalTwin['大地形影像'], null, null, null, 0.1)
    await fdapi.tileLayer.setStyle(digitalTwinStore.digitalTwin['苏州地形影像_Terrain'], null, null, null, 0.5)
}

然后我们分三步添加图层,分别是限飞范围,申请范围和无人机平台。

第一步添加限飞范围,限飞范围包括禁飞区和限飞区,首先我们先获取到这些区域的数据。在api下的home提供了获取这些geojson数据的接口,拿到这些数据后通过geoJSONLayer这个类进行绘制。由于返回的数据里面没有高度字段,所以我们手动添加一下,然后调整一下颜色透明度等等。

typescript 复制代码
let geoJSONLayerIds: string[] = [];
// 添加禁飞区
const addForbidFlyRegion = async () => {
    const { data } = await getForbidFlyRegion()
    const feature = data.features[0]
    feature.properties.height = 3000
    console.log(data,'data');
    
    //分类渲染器
    let classBreaksRenderer = {
        //材质样式
        style: 16,
        //默认符号化配置
        defaultSymbol: {
            //符号化类型枚举:0 simple-marker圆形点填充  1 simple-line线填充  2 simple-fill面填充 3 polygon3d填充
            symbolType: 2,
            //填充色
            color: [1, 0, 0, 0.5],
            //轮廓线
            outline: {
                //线宽
                width: 1,
                //颜色
                color: [1, 0, 0, 1]
            }
        },
        //按field高度属性拉高面
        visualVariables: [
            {
                //控制可视化显示的类型:高度
                type: VisualType.Height,
                //属性字段名称
                field: 'height',
                //属性字段类型
                fieldType: FieldType.Number
            }
        ]
    }

    //用分类渲染器添加GeoJSONLayer
    fdapi.geoJSONLayer.add({
        id: 'forbidFlyRegion_geojson',
        visible: true, //加载后是否显示
        rotation: [0, 0, 0], //图层旋转
        offset: [0, 0, 10], //基于原始位置的偏移量
        needProject: false, //开启投影转换
        onTerrain: false, //是否贴地
        collision: true, //开启碰撞
        sourceJson: data,
        renderer: classBreaksRenderer
    })
    geoJSONLayerIds.push('forbidFlyRegion_geojson');
}
// 添加限飞区
const addLimitFlyRegion = async () => {
    const { data } = await getLimitFlyRegion()
    const feature = data.features[0]
    feature.properties.height = 120
    //分类渲染器
    let classBreaksRenderer = {
        //材质样式
        style: 16,
        //默认符号化配置
        defaultSymbol: {
            //符号化类型枚举:0 simple-marker圆形点填充  1 simple-line线填充  2 simple-fill面填充 3 polygon3d填充
            symbolType: 2,
            //填充色
            color: [0, 0, 0, 0.3],
            //轮廓线
            outline: {
                //线宽
                width: 1,
                //颜色
                color: [0.5, 0.5, 0.5, 1]
            }
        },
        //按field高度属性拉高面
        visualVariables: [
            {
                //控制可视化显示的类型:高度
                type: VisualType.Height,
                //属性字段名称
                field: 'height',
                //属性字段类型
                fieldType: FieldType.Number
            }
        ]
    }
    //用分类渲染器添加GeoJSONLayer
    fdapi.geoJSONLayer.add({
        id: 'addLimitFlyRegion_geojson',
        visible: true, //加载后是否显示
        rotation: [0, 0, 0], //图层旋转
        offset: [0, 0, 10], //基于原始位置的偏移量
        needProject: false, //开启投影转换
        onTerrain: false, //是否贴地
        collision: true, //开启碰撞
        sourceJson: data,
        renderer: classBreaksRenderer
    })
    geoJSONLayerIds.push('addLimitFlyRegion_geojson');
}

第二步添加申请范围,我们通过polygon来进行添加。

typescript 复制代码
const polygonIds: string[] = []
// 添加申请范围
const addApplyCoverage = async () => {
    const { data } = await getApplyCoverage();
    const feature = data.features[0]
    const coordinates = feature.geometry.coordinates
    const polygonList: any[] = []
    coordinates.forEach((c: any, index: number) => {
        let p1 = {
            id: 'applyCoverage_' + index,
            coordinates: c,
            coordinateType: 0, //坐标系类型,取值范围:0为Projection类型,1为WGS84类型,2为火星坐标系(GCJ02),3为百度坐标系(BD09),默认值:0
            range: [0, 1000000], //可视范围:[近裁距离, 远裁距离],取值范围: [任意负值, 任意正值]
            color: [19 / 255, 103 / 255, 136 / 255, 0.5], //多边形的填充颜色
            frameColor: [0, 195 / 255, 255 / 255, 1],
            frameThickness: 200, //边框厚度
            intensity: 2, //亮度
            style: 0, //单色 请参照API开发文档选取枚举
            depthTest: false, //是否做深度检测 开启后会被地形高度遮挡
            priority: 1 //显示优先级 值越大显示越靠上
        }
        polygonList.push(p1)
        polygonIds.push(p1.id)
    })
    fdapi.polygon.add(polygonList)
}

第三步,添加无人机点位,我们通过marker添加。

typescript 复制代码
// 添加无人机平台
const addPlatformLayer = async () => {
    const { data } = await getPlatformData()
    const markerList: any = []
    data.features.forEach((item: any, index: number) => {
        const coordinate = item.geometry.coordinates
        const size = 0.8
        let o1 = {
            id: 'platform_marker_' + index,
            groupId: 'platform_marker',
            coordinate: coordinate, //坐标位置
            coordinateType: 0, //默认0是投影坐标系,也可以设置为经纬度空间坐标系值为1
            anchors: [(-56 / 2) * size, 72 * size], //锚点,设置Marker的整体偏移,取值规则和imageSize设置的宽高有关,图片的左上角会对准标注点的坐标位置。示例设置规则:x=-imageSize.width/2,y=imageSize.height
            imageSize: [56 * size, 72 * size], //图片的尺寸
            range: [1, 10000000], //可视范围
            imagePath: '@path:无人机.png', //显示图片路径

            autoHidePopupWindow: true, //失去焦点后是否自动关闭弹出窗口
            autoHeight: false, // 自动判断下方是否有物体
            displayMode: 1, //智能显示模式  开发过程中请根据业务需求判断使用四种显示模式
            clusterByImage: true, // 聚合时是否根据图片路径分类,即当多个marker的imagePath路径参数相同时按路径对marker分类聚合
            priority: 0, //避让优先级
            occlusionCull: false //是否参与遮挡剔除
        }
        markerList.push(o1)
    })
    fdapi.marker.add(markerList)
}

OK,添加完这三个图层之后就是通过按钮来控制这些图层的显示和隐藏了。首先我们找到这些按钮的位置,在children下的scope.vue文件下,然后添加点击事件,在点击事件中来控制图层的显示和隐藏。我们在刚刚的init文件夹下再抛出三个方法来控制图层。

dart 复制代码
//  切换显示隐藏-限飞范围
export const changeRestrictFlyLayer = async (show: boolean) => {
    if (show) {
        fdapi.geoJSONLayer.show(geoJSONLayerIds)
    } else {
        fdapi.geoJSONLayer.hide(geoJSONLayerIds)
    }
}
//  切换显示隐藏-申请范围
export const changeApplyCoverage = async (show: boolean) => {
    if (show) {
        fdapi.polygon.show(polygonIds)
    } else {
        fdapi.polygon.hide(polygonIds)
    }
}
//  切换显示隐藏-无人机平台
export const changePlatformLayer = async (show: boolean) => {
    if (show) {
        fdapi.marker.showByGroupId('platform_marker')
    } else {
        fdapi.marker.hideByGroupId('platform_marker')
    }
}

然后在scope中使用这些方法即可。

最后当组件卸载前需要做一些删除清理操作

dart 复制代码
export const exitLowAltitudeRange = async () => {
    await fdapi.weather.setDarkMode(false)
    await fdapi.infoTree.show(hideLayer.map(name => digitalTwinStore.digitalTwin[name]))
    await fdapi.tileLayer.setStyle(digitalTwinStore.digitalTwin['大地形影像'], null, null, null, 0.3)
    await fdapi.tileLayer.setStyle(digitalTwinStore.digitalTwin['苏州地形影像_Terrain'], null, null, null, 1)

    fdapi.geoJSONLayer.delete(geoJSONLayerIds)
    fdapi.polygon.delete(polygonIds)
    fdapi.marker.deleteByGroupId('platform_marker')
}

涉及的飞渡api

  • 通过geoJSONLayer添加面-fdapi.geoJSONLayer.add
  • 显示geoJSONLayer-fdapi.geoJSONLayer.show(geoJSONLayerIds)
  • 隐藏geoJSONLayer-fdapi.geoJSONLayer.hide(geoJSONLayerIds)
  • 通过polygon添加面-fdapi.polygon.add()
  • 显示polygon-fdapi.polygon.show(polygonIds)
  • 隐藏polygon-fdapi.polygon.hide(polygonIds)
  • 添加点-fdapi.marker.add()
  • 显示点-fdapi.marker.showByGroupId('platform_marker')
  • 隐藏点-fdapi.marker.hideByGroupId('platform_marker')
相关推荐
@PHARAOH1 小时前
HOW - 在 Mac 上的 Chrome 浏览器中调试 Windows 场景下的前端页面
前端·chrome·macos
月月大王3 小时前
easyexcel导出动态写入标题和数据
java·服务器·前端
JC_You_Know4 小时前
多语言网站的 UX 陷阱与国际化实践陷阱清单
前端·ux
Python智慧行囊4 小时前
前端三大件---CSS
前端·css
Jinuss4 小时前
源码分析之Leaflet中Marker
前端·leaflet
成都渲染101云渲染66664 小时前
blender云渲染指南2025版
前端·javascript·网络·blender·maya
聆听+自律4 小时前
css实现渐变色圆角边框,背景色自定义
前端·javascript·css
行走__Wz5 小时前
计算机学习路线与编程语言选择(信息差)
java·开发语言·javascript·学习·编程语言选择·计算机学习路线
-代号95275 小时前
【JavaScript】二十九、垃圾回收 + 闭包 + 变量提升
开发语言·javascript·ecmascript
牛马程序小猿猴5 小时前
17.thinkphp的分页功能
前端·数据库