编程技术文章分享与教程

网站首页 > 技术文章 正文

三维实现广州的行政区划(广州行政区划沿革)

hmc789 2024-11-15 19:39:22 技术文章 2 ℃

效果

记录一下智慧广州行政区划制作

显示效果需要相机调到正北位置,俯视即可。看似复杂o(╯□╰)o 实际上就是画几个polygon3d再打上marker点就完事了,一般分为几层(最顶上,中间,底部装饰)看图,

1. 第一步

布置环境: 清除所有图层,开启黑暗模式,设置相机位置

__g.camera.set(473660.9325, 2558256.117344, 227589.52, -85.993263, -84.615585, 0)
__g.weather.setDarkMode(true)
12

2.第二步

从.geojson文件中获取点位数据,需要每一个区块的点位数据(画出一块一块板块的效果);使用polygon3d画出每一区块的形状

/**
 * 添加顶部数据(第一层)
 */
const addTopLayer = () => {
    const polygonArr: any = []
    // 获取数据
    getLayer().then(async (data: any) => {
        data.features.forEach((item: any, index: number) => {
            const placeObj = placeNameArr.find((i: any) => i.code == item.properties.code)
            const top = {
                id: 'top_polygon_' + index,
                coordinates: item.geometry.coordinates,
                color: placeObj.color, //颜色值
                height: 200, //3D多边形的高度
                intensity: 0.3, //亮度
                style: 1,
                generateTop: true, //是否生成顶面
                generateSide: true, //是否生成侧面
                generateBottom: true //是否生成底面
            }
            polygon3dArr.push('top_polygon_' + index)
            polygonArr.push(top)

			// 生成边框
            const borderCoord = JSON.parse(JSON.stringify(item.geometry.coordinates))
            borderCoord.forEach((item: any) => {
                item.forEach((i: any) => {
                    i[2] = 400
                })
            })
            const border = {
                id: 'top_border_' + index, //polygon唯一标识id
                coordinates: borderCoord, //构成polygon的坐标点数组
                color: '#000',
                style: 8,
                intensity: 1,
                height: 1500 //3D多边形的高度
            }
            polygon3dArr.push('top_border_' + index)
            polygonArr.push(border)
        })
        //批量添加polygon
        const res = await __g.polygon3d.add(polygonArr, null)
          // 优化add
        if (res.result) {
            __g.polygon3d.show(polygon3dArr)
        }
    })
}

3.第三步

添加底部装饰图层(控制好每一层的高度)

/**
 * 添加底部装饰图层
 */
const addBottomLayer = () => {
    const polygonArr: Array<any> = []
    getBorder().then(async (data: any) => {
        data.features.forEach((item: any, index: number) => {
            const coordinate1 = JSON.parse(JSON.stringify(item.geometry.coordinates[0]))
            // 最底层蓝色-起始高度0,高度80
            coordinate1.forEach((item: Array<number>) => {
                item.forEach((i: any) => {
                    i[2] = -100
                })
            })
            const bottom1 = {
                id: 'bottom1_' + index, //polygon唯一标识id
                coordinates: coordinate1, //构成polygon的坐标点数组
                color: '#122e36',
                style: 2,
                intensity: 1,
                height: 100 //3D多边形的高度
            }
            polygon3dArr.push('bottom1_' + index)
            polygonArr.push(bottom1)
            const coordinate2 = JSON.parse(JSON.stringify(item.geometry.coordinates[0]))
            // 2层灰色-起始高度60,高度160
            coordinate2.forEach((item: Array<number>) => {
                item.forEach((i: any) => {
                    i[2] = -300
                })
            })
            const bottom2 = {
                id: 'bottom2_' + index, //polygon唯一标识id
                coordinates: coordinate2, //构成polygon的坐标点数组
                color: [0.2, 0.2, 0.2, 1],
                style: 2,
                height: 500 //3D多边形的高度
            }
            polygon3dArr.push('bottom2_' + index)
            polygonArr.push(bottom2)

            // 3层蓝绿色-起始高度120,高度100
            const coordinate3 = JSON.parse(JSON.stringify(item.geometry.coordinates[0]))
            coordinate3.forEach((item: Array<number>) => {
                item.forEach((i: any) => {
                    i[2] = -600
                })
            })
            const bottom3 = {
                id: 'bottom3_' + index, //polygon唯一标识id
                coordinates: coordinate3, //构成polygon的坐标点数组
                color: '#1d8eae',
                style: 4,
                height: 1000 //3D多边形的高度
            }
            polygon3dArr.push('bottom3_' + index)
            polygonArr.push(bottom3)
        })
        //批量添加polygon
        const res = await __g.polygon3d.add(polygonArr, null)
          // 优化add
        if (res.result) {
            __g.polygon3d.show(polygon3dArr)
        }
    })
}

4. 第四步

添加文字显示

/**
 * 添加中心点位
 */
const addMakerLayer = async () => {
    const markerArr: any = []
    const marker3dArr: any = []
    placeNameArr.forEach((item: any, index: number) => {
        const coordinate = item.coordinate
        coordinate[0] = coordinate[0] + 500
        coordinate[1] = coordinate[1] - 500
        coordinate[2] = 100
        const oMarker = {
            id: 'marker_label_' + index,
            coordinate: coordinate, //坐标位置
            range: [0, 1000000], //可视范围
            text: item.name, //显示的文字
            textRange: [0, 1000000], //文本可视范围[近裁距离, 远裁距离]
            textBackgroundColor: [0, 0, 0, 0], //文本背景颜色
            fontSize: 16, //字体大小
            textOffset: [0, 0, 0],
            fontOutlineSize: 1, //字体轮廓线大小
            fontColor: Color.Black, //字体颜色
            fontOutlineColor: Color.White, //字体轮廓线颜色
            displayMode: 2 //显示模式:相机移动时显示,参与避让聚合
        }
        shmarkerArr.push('marker_label_' + index)
        markerArr.push(oMarker)
    })
    //添加点
    const res = await __g.marker.add(markerArr)
    // 优化add
    if (res.result) {
        __g.marker.show(shmarkerArr)
    }
}

5. 第五步

控制显示行政区划的颜色和地图相似

/**
 * 获取数组颜色
 * @param colorArr
 */
const getColorArr = (colorArr: number[]) => {
    return [colorArr[0] / 255, colorArr[1] / 255, colorArr[2] / 255, 1]
}

6. 第六步

离开页面清除所有已经操作,使用show,hide方法是因为如果每次都clear再add的话,会浪费性能,而且一旦数据量大了之后,每次加载都会很漫长,使用show,hide则只add了一次,就算很慢也是第一次很慢,后面再显示就很快了

/**
 * 还原
 */
const cleanAdminStrativeArea = () => {
    __g.weather.setDarkMode(false)
    __g.polygon3d.hide(polygon3dArr)
    __g.marker.hide(shmarkerArr)
    __g.marker3d.hide(shmarker3dArr)
}

最后附上数据格式

const placeNameArr: any = [
    {
        name: '从化区',
        color: getColorArr([190, 232, 255]),
        coordinate: [469115.90625, 2617369.75, 499.98999],
        code: 440117000000
    }......
]

诶~就是这么简单,so easy !!!

更多有趣的文章可以访问往期文章,也可以查看这里

Tags:

标签列表
最新留言