0


地图引擎(WebGIS)之MapBox的基础使用

一、MapBox

官网: Mapbox Docs

JS语法模块: Mapbox GL JS | Mapbox

Openlayer、Leaflet相关应用:4、leaflet · 语雀

1.1、js显示(高德地图)

效果展示:

跟随鼠标操作可以放大缩小、俯仰角观看,左右摇摆式观看

代码分析:

 <!-- 1、导入mapbox的依赖 -->
    <script src='https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js'></script>
    <link href='https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css' rel='stylesheet' />
    <style>
        * {
            margin: 0;
            padding: 0
        }
        #map {
            width: 100vw;
            height: 100vh;
        }
    </style>
<body>
    <!-- 2、设置地图容器的挂载点 -->
    <div id="map"></div>
    <script>
        const gaode = {
            "version": 8,
            "sources": {
                "raster-tiles": {
                    "type": "raster",
                    "tiles": ["http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}"],
                    "tileSize": 256
                }
            },
            "layers": [{
                "id": "simple-tiles",
                "type": "raster",
                "source": "raster-tiles",
                "minzoom": 0,
                "maxzoom": 22
            }]
        }
        mapboxgl.accessToken = 'pk.eyJ1IjoiY2hlbmdiZW5jaGFvIiwiYSI6ImNsODU3aGRiODA0Y2UzcHBzZmFlcmdqZ2sifQ.8k59W_pB_Riwe6o-MneRlA'
        const map = new mapboxgl.Map({
            /* 相当于openlayer的target */
            container: 'map', // container ID
            /* 相当于openlayer的layers */
            style: gaode, //显示高德地图,原来是国际地图
            center: [114.30, 30.50], // 设置经纬度 [lng, lat]
            zoom: 2,
            /* 属性值为globe显示球形 ,默认是平面式的*/
            projection: 'globe',
            pitch: 0,//俯仰角 0~90(默认值是0)
            bearing:0//水平角
        });
       map.on("style.load", () => {
            map.setFog({
                color: 'red',//大气层颜色
                'high-color': 'yellow',//高空颜色
                'space-color': 'green'//星空颜色
            })//设置背景
            map.doubleClickZoom.disable()//禁止双击地图放大
        })
       map.on('click', () => {
            // var pitch = map.getPitch()
            // pitch += 10;
            // map.setPitch(pitch);//点击图层,俯仰角度改变
            setInterval(() => {
                let bearing = map.getBearing()
                bearing += 10;
                map.setBearing(bearing)
            }, 50);//借助定时器实现“沙盘旋转”效果
        })
    </script>
</body>

1.2、l7&mapbox

L7(地理数据可视化)官网: 快速上手 | AntV L7 地理空间数据可视化引擎

科普:7代表7大洲

    <!-- 1、导入mapbox的依赖 -->
    <script src='https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js'></script>
    <link href='https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css' rel='stylesheet' />
    <script src="https://unpkg.com/@antv/l7"></script>
<script>
const token = 'pk.eyJ1IjoiY2hlbmdiZW5jaGFvIiwiYSI6ImNsODU3aGRiODA0Y2UzcHBzZmFlcmdqZ2sifQ.8k59W_pB_Riwe6o-MneRlA'
        const scene = new L7.Scene({
            id: 'map',
            map: new L7.Mapbox({
                style: gaode, // 样式URL
                center: [114.050008, 22.529272],
                pitch: 0,
                zoom: 14,
                projection: 'globe',
                token,
            }),
        });
        const map = scene.map;
        map.on('style.load', () => {
            map.setFog({})
        })
        /* 地图控件 */
        scene.on('loaded', () => {
            /* 地图主题控件 */
            const mapTheme = new L7.MapTheme();
            scene.addControl(mapTheme);
        });
</script>

1.3、案例

1.3.1、加载深圳市数据

https://gw.alipayobjects.com/os/basement_prod/972566c5-a2b9-4a7e-8da1-bae9d0eb0117.json

效果展示:

核心代码:

 // L7.PolyonLayer
        scene.on('loaded', () => {
            fetch('https://gw.alipayobjects.com/os/basement_prod/972566c5-a2b9-4a7e-8da1-bae9d0eb0117.json')
                .then(res => res.json())
                .then(data => {
                    console.log(data);
                    const layer = new L7.PolyonLayer({});//实例化(区域)图层
                    layer.source(data)//加载数据
                        .shape('extrude')//视图区域层有高度
                        .size('h20')//可以直接获取geojson中properties里的属性值
                        .active(true)
                    scene.addLayer(layer)
                })
        })

1.3.2、漫游(flyTo)效果

    <style>
        #btn {
            width: 200px;
            height: 50px;
            position: fixed;
            top: 20px;
            right: 30px;
            z-index: 100;
        }
    </style>
    <button onclick="resetMap()" id="btn">复位地图</button>
    <script>
        // 漫游效果:点击地图飞行到武汉,点击复位恢复原始状态
        map.on('click', () => {
            map.flyTo({
                zoom: 14,
                pitch: 90,
                center: [114.30, 30.50]//中心点
            })
        })
        function resetMap() {
            map.flyTo({
                zoom: 1.5,
                pitch: 0,
                center: [114.30, 30.50]
            })
        }
    </script>

1.3.3、底层(layer-style)切换

设置不同样式:Styles API | API Docs | Mapbox

    <style>
        #btn {
            width: 200px;
            height: 50px;
            position: fixed;
            top: 20px;
            right: 30px;
            z-index: 100;
        }
    </style>
    <button id="btn">模式切换</button>
    <script>
        let isToggle = false;
        let btn = document.getElementById("btn");
        btn.onclick = function () {
            isToggle = !isToggle;
            if (isToggle) {
                map.setStyle('mapbox://styles/mapbox/satellite-streets-v12');
                this.innerHTML = '卫星地图';
            } else {
                map.setStyle('mapbox://styles/mapbox/streets-v12');
                this.innerHTML = '街景地图';
            }
            console.log(isToggle, this.innerHTML);
        }
    </script>

1.3.4、地形数据加载

相当于地图中的山脉形状也清晰可见了。

<script>    
    // DEM(数据高程模型)
        map.addSource('mapbox-dem', {
            'type': 'raster-dem',
            url: 'mapbox://mapbox.mapbox-terrain-dem-v1'
        })
        map.setTerrain({ source: 'mapbox-dem', exaggeration: 1.5 })
</script>

1.3.5、事件控制地球自转与暂停

地球自转本质:每间隔一段时间经度累加,通过**easeTo()开始旋转,通过stop()**停止旋转;

//===========================模仿原理====================
map.on('click', () => {
            setInterval(() => {
                let center = map.getCenter();
                center.lng += 10;//地球自转:经度累加
                map.setCenter(center)
            }, 50)
})
//===========================官方api实现====================
        let isUserInterface = false;
        map.on('click', () => {
            isUserInterface = !isUserInterface;
            if (isUserInterface) {
                map.stop();//停止旋转
            } else {
                rotateMap();
            }
        })
        map.on('moveend', () => {
            rotateMap();//当地球停止旋转时,触发旋转事件
        })
        function rotateMap() {
            const zoom = map.getZoom()
            if (zoom < 5 && !isUserInterface) {
                let center = map.getCenter();
                center.lng += 10;//地球自转:经度累加
                map.easeTo({//easeTo相当于setInterval
                    center,
                    duration: 1000,//间隔时长
                    easing: n => n
                })
            }
        }
        rotateMap();

1.3.6、沙盘的白天黑夜切换

其实就是设置不同的setFog;

        map.on('moveend', () => {
            rotateMap();//当地球停止旋转时,触发旋转事件
        })
        function rotateMap() {
            let bearing = map.getBearing();
            bearing += 10;
            if (bearing < 0) {
                map.setFog({
                    range: [-1, 2],
                    'horizon-blend': 0.3,
                    color: "#242B4B",//黑夜
                    "high-color": '#161B36',
                    "space-color": '#0B1026',
                    'star-intensity': 0.8
                })
            } else {
                map.setFog({
                    range: [-1, 2],
                    'horizon-blend': 0.3,
                    color: "white",//白天
                    "high-color": '#add8e6',
                    "space-color": '#d8f2ff',
                    'star-intensity': 0.0
                })
            }
            map.easeTo({//easeTo相当于setInterval
                bearing: bearing,
                duration: 1000,//间隔时长
                easing: n => n
            })
        }

1.3.7、地图控件

<head>
    <!-- 汉化包 -->
    <script src='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-language/v1.0.0/mapbox-gl-language.js'></script>
</head>   
<script>
        map.addControl(new mapboxgl.FullscreenControl());//全屏控件
        map.addControl(new mapboxgl.NavigationControl(),
            // top-left、top-right、bottom-left、bottom-right
            'top-right');//导航控件
        map.addControl(new mapboxgl.ScaleControl(),'top-right');//比例尺控件
        // 鼠标位置控件
        map.on('mousemove', (evt) => {
            let { lng, lat } = evt.lngLat;
            // 随着鼠标移动获取对应的经纬度
            document.getElementById('mouse').innerHTML = `经度:${lng.toFixed(2)},纬度:${lat.toFixed(2)}`
        })
        // 汉化控件(将国际命名转为汉字)
        map.addControl(new MapBoxLanguage({
            defaultLanguage: 'zh-Hans'
        }))
</script>

1.3.8、geojson加载数据

获取湖北省的地图数据:DataV.GeoAtlas地理小工具系列

<head>
    <!--jquery -->
    <script src='https://lib.baomitu.com/jquery/2.2.4/jquery.js'></script>
</head>   
<script>       、
 map.on("style.load", () => {
            map.setFog({})//设置背景
            map.doubleClickZoom.disable()//禁止双击地图放大
            $.ajax({
                url: 'https://geo.datav.aliyun.com/areas_v3/bound/420000_full.json'
            }).then(res => {
                map.addLayer({
                    id: 'hubei',
                    type: 'fill',
                    source: {
                        type: 'geojson',
                        data: res
                    },
                    // 绘制地图样式
                    paint: {
                        'fill-color': '#ff2d51',
                        'fill-opacity': .5
                    }
                })
            })
        })
</script> 

1.3.9、addSource

addLayer可以单独使用,也可以结合addSource一起使用;

     // http请求后的图层已经加载到map的style属性中了
                map.addSource("hubei", {
                    type: 'geojson',
                    data: res
                })
                map.addLayer({
                    id: 'hubei-layer',
                    type: 'fill',
                    source: "hubei",
                    // 绘制地图样式
                    paint: {
                        'fill-color': '#ff2d51',
                        'fill-opacity': .5
                    }
                })

1.3.10、设置鼠标形状

map.on("load", function () {
            map.on('mouseenter', 'Point', () => {
                map.getCanvas().style.cursor = 'pointer';
            });
            map.on('mouseleave', 'Point', () => {
                map.getCanvas().style.cursor = 'default';
            });
        })

1.4、vue3中引入并应用

1.4.1、安装配置

(1)、npm i mapbox-gl

(2)、设置

.env,这里的token 是临时的,可以去官网注册一个新的
VITE_TOKEN ='pk.eyJ1IjoiY2hlbmdiZW5jaGFvIiwiYSI6ImNsODU3aGRiODA0Y2UzcHBzZmFlcmdqZ2sifQ.8k59W_pB_Riwe6o-MneRlA'

(3)、配置main.js

1.4.2、代码应用

(1)、初始化地图

<template>
  <div id="map"></div>
</template>
<script setup>
import mapboxGl from "mapbox-gl";
import { onMounted } from "vue";
mapboxGl.accessToken = import.meta.env.VITE_TOKEN;
onMounted(() => {
  const map = new mapboxGl.Map({
    /* target-ol */
    container: "map", // container ID
    style: "mapbox://styles/mapbox/streets-v12", // style URL
    center: [114.3, 30.5], // starting position [lng, lat]
    zoom: 12, // starting zoom
  });
});
</script>
<style scoped>
#map{
  position: absolute;
  top:0;
  right:0;
  left:0;
  bottom: 0;
}
</style>

(2)、将地图挂载到全局

BoxMap.vue代码:

<template>
  <div id="map"></div>
</template>
<script setup>
import mapboxGl from "mapbox-gl";
import { onMounted } from "vue";
import { app } from "../main";
mapboxGl.accessToken = import.meta.env.VITE_TOKEN;
onMounted(() => {
  const map = new mapboxGl.Map({
    /* target-ol */
    container: "map", // container ID
    style: "mapbox://styles/mapbox/streets-v12", // style URL
    center: [114.3, 30.5], // starting position [lng, lat]
    zoom: 12, // starting zoom
  });
  app.provide("$map", map);
});
</script>
<style scoped>
#map {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
}
</style>

BoxGeoJSON.vue代码:geojson加载-点击事件漫游

<template>
  <div>
    <!-- 点击按执行飞行 -->
    <button id="btn" @click="handleClick">按钮</button>
  </div>
</template>
<script setup>
import { onMounted, inject } from "vue";
let $map;
onMounted(() => {
  $map = inject("$map");
  let url = "https://geo.datav.aliyun.com/areas_v3/bound/420100_full.json";
  $map.on("style.load", () => {
    $map.addLayer({
      id: "wuhan",
      type: "fill",
      source: {
        type: "geojson",
        data: url,
      },
      paint: {
        "fill-color": "#fff",
        "fill-opacity": 0.8,
      },
    });
  });
});
const handleClick = () => {
  $map.flyTo({
    zoom: 4,
  });
};
</script>
<style scoped>
#btn {
  width: 200px;
  height: 50px;
  background-color: #ff2d51;
  position: fixed;
  z-index: 100;
  top: 10px;
  right: 50px;
}
</style>

注意:这些只是基础使用,其他的属性和方法自行查找官网,慢慢研究。


本文转载自: https://blog.csdn.net/qq_44930306/article/details/138790426
版权归原作者 野槐 所有, 如有侵权,请联系我们删除。

“地图引擎(WebGIS)之MapBox的基础使用”的评论:

还没有评论