• 百度地图开发入门(6):3D建筑


    原创不易~看完若对你有所帮助,记得点一个赞哈,这就是对我最大的支持了!

    这里将会介绍基于百度地图与大数据来实现的立方体图形,这里就需要掌握面的概念:

    这里需要掌握shapeLayer:https://lbsyun.baidu.com/solutions/mapvdata,他可以提供一系列坐标点来形成一个面,最后多个面可以形成一个多边形。

    1. 绘制一个面

    <body>
    
        <div id="map_container"></div>
    
        <script>
    
            const map = initBMap();
    
            const data = initData();
    
            setData(data, map);
    
    
    
            // 初始化百度地图
    
            function initBMap() {
    
                // 引入的common库所作的处理
    
                // mapv提供了api,根据名称获取坐标
    
                const cityCenter = mapv.utilCityCenter.getCenterByCityName('北京');
    
                const map = initMap({
    
                    center: [cityCenter.lng, cityCenter.lat],
    
                    zoom: 17,
    
                    tilt: 80,
    
                    heading: -45.3
    
                })
    
                return map;
    
    
    
            }
    
    
    
    
    
            // 准备数据源
    
            function initData() {
    
                let data = [{
    
                    geometry: {
    
                        type: 'Polygon',
    
                        // type切换为polygon - 多边形
    
                        // 坐标是一个三维数组
    
                        coordinates: [
    
                            [
    
                                // 第一种坐标定位,传入经纬度
    
                                [116.392394, 39.910683],
    
                                [116.405976, 39.927727],
    
                                [116.420996, 39.910351]
    
                            ]
    
                        ]
    
                    },
    
                    // height表示多边形高度,必要
    
                    properties: {
    
                        height: 100, // 多边形高度
    
                    }
    
                }];
    
    
    
                return data;
    
            }
    
    
    
    
    
            // 绘制数据源 
    
            function setData(data, map) {
    
                const view = new mapvgl.View({ map });
    
                const shapeLayer = new mapvgl.ShapeLayer({
    
                    color: 'blue',
    
                    opacity: 0.3,
    
                    style: 'normal'
    
                })
    
                view.addLayer(shapeLayer);
    
                shapeLayer.setData(data);
    
    
    
    
    
            }
    
    
    
    
    
    
    
        </script>
    
    </body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133

    2. 墨卡托坐标系 - 墨卡托投影

    就是把圆球形地图变成一个直角坐标系,这样坐标系每一个点就可以对应到地球上的经纬度坐标,这种坐标就是墨卡托坐标。

    这里官方由这样的API来实现:

    https://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition

    这里我们可以尝试调用一下这个接口(需要你的密钥)根据经纬度获取墨卡托坐标,后续官方案例中使用的就是墨卡托坐标系。

    3. 重庆市3D建筑图

    这里我们来学习一下官方的一个示例:https://mapv.baidu.com/gl/examples/editor.html#shape.html

    首先我们基于这个案例的接口获取并处理一下数据源:

     // 准备数据源
    
            function initData() {
    
                let data = [];
    
                // 直接获取视频教程接口拿到三维数组,每一个数组都是内部面的构成数组
    
                // 面构成数组第一个值是高度,后续值都是坐标系(xy顺序)
    
                fetch('https://www.youbaobao.xyz/datav-res/examples/chongqing.json')
    
                    .then(res => res.json())
    
                    .then(res => {
    
                        // 存放多边形面数据
    
                        const polygons = [];
    
                        const len = res.length;
    
                        for (let i = 0; i < len; i++) {
    
                            const line = res[i];
    
                            const polygon = [];
    
                            // 官方提供的转换墨卡托方式
    
                            const pt = [line[1] * 512, line[2] * 512];
    
                            for (let j = 3; j < line.length; j += 2) {
    
                                // 官方拿到的数据源需要作的处理 - 获取经纬度
    
                                pt[0] += line[j] / 100 / 2;
    
                                pt[1] += line[j + 1] / 100 / 2;
    
                                polygon.push([pt[0], pt[1]]);
    
                            }
    
                            polygons.push({
    
                                geometry: {
    
                                    type: 'Polygon',
    
                                    coordinates: [polygon]
    
                                },
    
                                properties: {
    
                                    height: line[0] / 2
    
                                }
    
                            })
    
                        }
    
                        console.log(polygons)
    
                    });
    
    
    
                return data;
    
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    polygons里面有一个三维数组,里面包括墨卡托坐标以及高度,每一个面数据都是这样的结构

    最后我们是异步获取data,要基于promise封装下:

    <body>
    
        <div id="map_container"></div>
    
        <script>
    
            const map = initBMap();
    
            initData().then(data => {
    
                setData(data, map);
    
            });
    
    
    
    
    
            // 初始化百度地图
    
            function initBMap() {
    
                // 引入的common库所作的处理
    
                // mapv提供了api,根据名称获取坐标
    
                const cityCenter = mapv.utilCityCenter.getCenterByCityName('重庆');
    
                const map = initMap({
    
                    center: [cityCenter.lng, cityCenter.lat],
    
                    zoom: 17,
    
                    tilt: 80,
    
                    heading: -45.3
    
                })
    
                return map;
    
    
    
            }
    
    
    
    
    
            // 准备数据源
    
            function initData() {
    
                // 直接获取视频教程接口拿到三维数组,每一个数组都是内部面的构成数组
    
                // 面构成数组第一个值是高度,后续值都是坐标系(xy顺序)
    
                return fetch('https://www.youbaobao.xyz/datav-res/examples/chongqing.json')
    
                    .then(res => res.json())
    
                    .then(res => {
    
                        // 存放多边形面数据
    
                        const polygons = [];
    
                        const len = res.length;
    
                        for (let i = 0; i < len; i++) {
    
                            const line = res[i];
    
                            const polygon = [];
    
                            // 官方提供的转换墨卡托方式
    
                            const pt = [line[1] * 512, line[2] * 512];
    
                            for (let j = 3; j < line.length; j += 2) {
    
                                // 官方拿到的数据源需要作的处理 - 获取经纬度
    
                                pt[0] += line[j] / 100 / 2;
    
                                pt[1] += line[j + 1] / 100 / 2;
    
                                polygon.push([pt[0], pt[1]]);
    
                            }
    
                            polygons.push({
    
                                geometry: {
    
                                    type: 'Polygon',
    
                                    coordinates: [polygon]
    
                                },
    
                                properties: {
    
                                    height: line[0] / 2
    
                                }
    
                            })
    
                        }
    
                        console.log(polygons)
    
                        return polygons;
    
                    });
    
            }
    
    
    
    
    
            // 绘制数据源 
    
            function setData(data, map) {
    
                const view = new mapvgl.View({ map });
    
                const shapeLayer = new mapvgl.ShapeLayer({
    
                    color: 'rgba(194, 147, 75, 0.8)', // 柱状图颜色
    
                    style: 'normal'
    
                })
    
                view.addLayer(shapeLayer);
    
                shapeLayer.setData(data);
    
    
    
    
    
            }
    
    
    
    
    
    
    
        </script>
    
    </body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157

    接着我们看看其他layer的配置参数:

    // 绘制数据源 
    
            function setData(data, map) {
    
                const view = new mapvgl.View({ map });
    
                const shapeLayer = new mapvgl.ShapeLayer({
    
                    color: 'rgba(194, 147, 75, 0.8)', // 柱状图颜色
    
                    style: 'windowAnimation', // 大楼会有窗户
    
                    blend: 'lighter', // 汇聚时效果
    
                    riseTime: '2000', // 楼房会有升起动画2s
    
                    enablePicked: true, // 可以选中shape
    
                    selectedColor: 'red',
    
                    autoSelect: true, //根据鼠标位置选中
    
                    onClick: (e) => {
    
                        console.log(e)
    
                    }
    
    
    
                })
    
                view.addLayer(shapeLayer);
    
                shapeLayer.setData(data);
    
    
    
    
    
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    点击一个建筑后可以获取相关信息,可以帮助我们进行标注等后续操作开发:

  • 相关阅读:
    kafka-消费者服务搭建&配置&简单消费(SpringBoot整合Kafka)
    小山菌_代码随想录算法训练营第二十七天| 93.复原IP地址 、
    SpringCloud - Spring Cloud Netflix 之 Zuul网关;路由(十一)
    solidworls视图与模型及绘图操作快捷方式
    一篇文章让你掌握HTML+CSS
    elasticsearch常用命令
    NumPy 1.26 中文文档翻译完成
    博客园商业化之路-众包平台:从第一单看基于「开发任务」的定位
    从搭建SpringMVC环境到实现增删改查&&文件上传-文件下载
    AutoGluon --AWS开源的AutoML框架
  • 原文地址:https://blog.csdn.net/sdsh1880gm/article/details/125291341