从零开始Vue项目中使用MapboxGL开发三维地图教程(二)Mapbox地图样式

1、Mapbox地图样式定义

Mapbox地图样式:按照Mapbox地图样式规范中描述的模式定义的一个JSON对象,或者是此类JSON的URL。可以接受null值以允许手动添加样式。

要从Mapbox API加载样式,可以使用表单的URL

mapbox://styles/:owner/:style

其中:owner是您的Mapbox帐户名,:style是样式ID。

2、Mapbox默认地图样式

样式名称 样式URL 样式image
Mapbox Streets街道底图 mapbox://styles/mapbox/streets-v12 在这里插入图片描述
Mapbox Outdoors户外底图 mapbox://styles/mapbox/outdoors-v12 在这里插入图片描述
Mapbox Light mapbox://styles/mapbox/light-v11 在这里插入图片描述
Mapbox Dark mapbox://styles/mapbox/dark-v11 在这里插入图片描述
Mapbox Satellite卫星底图 mapbox://styles/mapbox/satellite-v9 在这里插入图片描述
Mapbox Satellite Streets卫星街道混合底图 mapbox://styles/mapbox/satellite-streets-v12 在这里插入图片描述
Mapbox Navigation Day导航底图(白天) mapbox://styles/mapbox/navigation-day-v1 在这里插入图片描述
Mapbox Navigation Night导航底图(晚上) mapbox://styles/mapbox/streets-v12 在这里插入图片描述

3、Mapbox地图样式对象

Mapbox地图样式对象样式对象必须符合以下规则:

  • 必须是有效的JSON

  • 必须与地图框样式规范的最新版本对齐

  • 可由不超过15个来源组成

  • 样式正文中不能包含样式规范中列出的键以外的任何键

  • 源对象中的url属性必须是有效的Mapbox集合ID

  • 仅支持光栅和矢量源

mapbox地图样式对象例子:

{
    
    
  "version": 8,
  "name": "{name}",
  "metadata": "{metadata}",
  "sources": "{sources}",
  "sprite": "mapbox://sprites/{username}/{style_id}",
  "glyphs": "mapbox://fonts/{username}/{fontstack}/{range}.pbf",
  "layers": ["{layers}"],
  "created": "2015-10-30T22:18:31.111Z",
  "id": "{style_id}",
  "modified": "2015-10-30T22:22:06.077Z",
  "owner": "{username}",
  "visibility": "private",
  "protected": false,
  "draft": true
}

样式对象属性说明表:

Property Type Description
version number The style specification version number.
name string A human-readable name for the style.
metadata object Information about the style that is used in Mapbox Studio.
sources object Sources supply the data that will be shown on the map.
layers array Layers will be drawn in the order of this array.
created string The date and time the style was created.
id string The ID of the style.
modified string The date and time the style was last modified.
owner string The username of the style owner.
visibility string Access control for the style, either public or private. Private styles require an access token belonging to the owner. Public styles may be requested with an access token belonging to any user.
protected boolean Indicates whether the style is protected (true) or not (false). Protected styles cannot be edited and deleted.
draft boolean Indicates whether the style is a draft (true) or whether it has been published (false).

4、切换地图样式的案例

4.1 加载mapbox默认地图

完整代码(vue版本):

<template>
  <div>
    <div id="map"></div>

    <div id="menu">
      <input
        id="satellite-streets-v12"
        type="radio"
        name="rtoggle"
        value="satellite"
        checked="checked"
      />
      <!-- See a list of Mapbox-hosted public styles at -->
      <!-- https://docs.mapbox.com/api/maps/styles/#mapbox-styles -->
      <label for="satellite-streets-v12">卫星街道混合</label>
      <input id="light-v11" type="radio" name="rtoggle" value="light" />
      <label for="light-v11">亮色</label>
      <input id="dark-v11" type="radio" name="rtoggle" value="dark" />
      <label for="dark-v11">暗色</label>
      <input id="streets-v12" type="radio" name="rtoggle" value="streets" />
      <label for="streets-v12">街道</label>
      <input id="outdoors-v12" type="radio" name="rtoggle" value="outdoors" />
      <label for="outdoors-v12">户外</label>
    </div>
  </div>
</template>

<script>
export default {
    
    
  data() {
    
    
    return {
    
    
      map: null,
    };
  },

  components: {
    
    },
  created() {
    
    },
  mounted() {
    
    
    this.initmap();
  },
  computed: {
    
    },

  methods: {
    
    
    initmap() {
    
    
      this.$mapboxgl.accessToken =
        "pk.xxxoidGlnZXJiZ3AyMDIwIiwiYSI6ImNsaGhpb3Q0ZTBvMWEzcW1xcXd4aTk5bzIifQ.4mA7mUrhK09N4vrrQfZA_Q";

      this.map = new this.$mapboxgl.Map({
    
    
        container: "map",
        style: "mapbox://styles/mapbox/satellite-streets-v12", //mapbox://styles/mapbox/satellite-streets-v12
        projection: "globe",
        center: [104.07, 30.67],
        zoom: 3,
        // pitch: 60, //视野倾斜,0-60
        // bearing: -17.6,//视野旋转角度
      });
      const layerList = document.getElementById("menu");
      const inputs = layerList.getElementsByTagName("input");

      for (const input of inputs) {
    
    
        input.onclick = (layer) => {
    
    
          const layerId = layer.target.id;
          this.map.setStyle("mapbox://styles/mapbox/" + layerId);
        };
      }
	}
  },
};
</script>

<style>
body {
    
    
  margin: 0;
  padding: 0;
}
#map {
    
    
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}

#menu {
    
    
  position: absolute;
  background: #efefef;
  padding: 10px;
  font-family: "Open Sans", sans-serif;
}
</style>


效果图:
在这里插入图片描述
在这里插入图片描述

4.2 加载天地图的在线切片数据

完整代码:

<template>
  <div id="map">
    <div style="z-index: 9999; position: absolute">
      <el-radio-group
        v-model="currentMap"
        size="small"
        @change="handleSelectMapstyle"
      >
        <el-radio-button label="streets-v11">街道图</el-radio-button>
        <el-radio-button label="satellite-streets-v12">卫星图</el-radio-button>
        <el-radio-button label="tianditu">天地图</el-radio-button>
      </el-radio-group>
    </div>
    <div style="z-index: 9999; position: absolute; right: 50px">
      <el-radio-group
        v-model="currentLanguage"
        size="small"
        @change="handleSelectLanguage"
      >
        <el-radio-button label="en">English</el-radio-button>
        <el-radio-button label="zh-Hans">中文简体</el-radio-button>
      </el-radio-group>
    </div>
  </div>
</template>

<script>
// import mapboxgl from "mapbox-gl";
import MapboxLanguage from "@mapbox/mapbox-gl-language";
export default {
    
    
  data() {
    
    
    return {
    
    
      currentMap: "streets-v11",
      currentLanguage: "zh-Hans",
      map: "",
    };
  },

  components: {
    
    },
  created() {
    
    
    this.$mapboxgl.setRTLTextPlugin(
      "https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.1.0/mapbox-gl-rtl-text.js"
    );
  },
  mounted() {
    
    
    this.initmap();
  },
  computed: {
    
    },

  methods: {
    
    
    //初始化mapbox地图
    initmap() {
    
    
      this.$mapboxgl.accessToken =
        "pk.xxxxxxx.4mA7mUrhK09N4vrrQfZA_Q";

      this.map = new this.$mapboxgl.Map({
    
    
        container: "map",
        style: "mapbox://styles/mapbox/streets-v11", //mapbox://styles/mapbox/satellite-streets-v12
        projection: "globe",
        center: [104.07, 30.67],
        zoom: 3,
        // pitch: 60, //视野倾斜,0-60
        // bearing: -17.6,//视野旋转角度
      });

      this.map.addControl(
        new MapboxLanguage({
    
    
          defaultLanguage: "zh-Hans",
        })
      );
    },
    //选择底图方法
    handleSelectMapstyle(item) {
    
    
      if(item == 'tianditu'){
    
    
        const tianditustyle = {
    
    
          "version": 8,
          "sources": {
    
    
              //天地图底图分成底图和注记两部分,需设置两个数据源
              "tiandituimg": {
    
    
                  "type": "raster",
                  "tiles": ["https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=xxxxxxx"],
                  "tileSize": 256
              },
              "tiandituano": {
    
    
                  "type": "raster",
                  "tiles": ["https://t0.tianditu.gov.cn/DataServer?T=cva_c&x={x}&y={y}&l={z}&tk=xxxxxxx"],
                  "tileSize": 256
              },
              // "tiandituano1": {
    
    
              //     "type": "raster",
              //     "tiles": ["http://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={x}&TILECOL={y}&tk=xxxxxxx"],
              //     "tileSize": 256
              // }
          },
          "layers": [{
    
    
                  //根据数据源,添加两个图层
                  "id": "tiandituimg",
                  "type": "raster",
                  "source": "tiandituimg",
                  "minzoom": 0,
                  "maxzoom": 18
              }, {
    
    
                  "id": "tiandituano",
                  "type": "raster",
                  "source": "tiandituano",
                  "minzoom": 0,
                  "maxzoom": 18
              },
              //  {
    
    
              //     "id": "tiandituano1",
              //     "type": "raster",
              //     "source": "tiandituano1",
              //     "minzoom": 0,
              //     "maxzoom": 18
              // }
          ]
        }

        this.map.setStyle(tianditustyle)
      }

      this.map.setStyle("mapbox://styles/mapbox/" + item);
    },
    //选择底图方法
    handleSelectLanguage(language) {
    
    
      console.log(language);
      // and the new property value.
      this.map.setLayoutProperty("country-label", "text-field", [
        "get",
        `name_${
      
      language}`,
      ]);
    },
  },
};
</script>

<style>
body {
    
    
  margin: 0;
  padding: 0;
}
#map {
    
    
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}

#menu {
    
    
  position: absolute;
  background: #efefef;
  padding: 10px;
  font-family: "Open Sans", sans-serif;
}
</style>

效果展示:
在这里插入图片描述

5、mapbox设置地图语言为中文

5.1 使用语言插件进行切换

安装语言插件:

npm i @mapbox/mapbox-gl-language@0.10.0

完整源码:

<template>
  <div id="map">
    <div style="z-index: 9999; position: absolute">
      <el-radio-group v-model="currentMap" size="small" @change="handleSelect">
        <el-radio-button label="streets-v11">街道图</el-radio-button>
        <el-radio-button label="satellite-v9">卫星图</el-radio-button>
      </el-radio-group>
    </div>
  </div>
</template>

<script>
// import mapboxgl from "mapbox-gl";
import MapboxLanguage from "@mapbox/mapbox-gl-language";
export default {
    
    
  data() {
    
    
    return {
    
    
      currentMap: "streets-v11",
      map: "",
    };
  },

  components: {
    
    },
  created() {
    
    
    this.$mapboxgl.setRTLTextPlugin(
      "https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.1.0/mapbox-gl-rtl-text.js"
    );
  },
  mounted() {
    
    
    this.initmap();
  },
  computed: {
    
    },

  methods: {
    
    
    //初始化mapbox地图
    initmap() {
    
    
      this.$mapboxgl.accessToken =
        "pk.11111idGlnZXJiZ3AyMDIwIiwiYSI6ImNsaGhpb3Q0ZTBvMWEzcW1xcXd4aTk5bzIifQ.4mA7mUrhK09N4vrrQfZA_Q";

      this.map = new this.$mapboxgl.Map({
    
    
        container: "map",
        style: "mapbox://styles/mapbox/streets-v11", //mapbox://styles/mapbox/satellite-streets-v12
        // projection: "globe",
        center: [104.07, 30.67],
        zoom: 3,
        // pitch: 60, //视野倾斜,0-60
        // bearing: -17.6,//视野旋转角度
      });

      this.map.addControl(
        new MapboxLanguage({
    
    
          defaultLanguage: "zh-Hans",
        })
      );
    },
    //选择底图方法
    handleSelect(item) {
    
    
      this.map.setStyle("mapbox://styles/mapbox/" + item);
    },
  },
};
</script>

<style>
body {
    
    
  margin: 0;
  padding: 0;
}
#map {
    
    
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}

#menu {
    
    
  position: absolute;
  background: #efefef;
  padding: 10px;
  font-family: "Open Sans", sans-serif;
}
</style>

效果:
在这里插入图片描述

5.2 使用setLayoutProperty动态切换语言

完整demo:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Change a map's language</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js"></script>
<style>
body {
    
     margin: 0; padding: 0; }
#map {
    
     position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<style>
    #buttons {
    
    
        width: 90%;
        margin: 0 auto;
    }
    .button {
    
    
        display: inline-block;
        position: relative;
        cursor: pointer;
        width: 20%;
        padding: 8px;
        border-radius: 3px;
        margin-top: 10px;
        font-size: 12px;
        text-align: center;
        color: #fff;
        background: #ee8a65;
        font-family: sans-serif;
        font-weight: bold;
    }
</style>
<div id="map"></div>
<ul id="buttons">
    <li id="button-fr" class="button">French</li>
    <li id="button-ru" class="button">Russian</li>
    <li id="button-de" class="button">German</li>
    <li id="button-es" class="button">Spanish</li>
</ul>
<script>
	mapboxgl.accessToken = 'pk.eyJ1IjoidGlnZXJiZ3AyMDIwIiwiYSI6ImNsaGhpb3Q0ZTBvMWEzcW1xcXd4aTk5bzIifQ.4mA7mUrhK09N4vrrQfZA_Q';
    const map = new mapboxgl.Map({
    
    
        container: 'map',
        // Choose from Mapbox's core styles, or make your own style with Mapbox Studio
        style: 'mapbox://styles/mapbox/light-v11',
        center: [16.05, 48],
        zoom: 2.9
    });

    document.getElementById('buttons').addEventListener('click', (event) => {
    
    
        const language = event.target.id.substr('button-'.length);
        // Use setLayoutProperty to set the value of a layout property in a style layer.
        // The three arguments are the id of the layer, the name of the layout property,
        // and the new property value.
        map.setLayoutProperty('country-label', 'text-field', [
            'get',
            `name_${
      
      language}`
        ]);
    });
</script>

</body>
</html>

猜你喜欢

转载自blog.csdn.net/weixin_43025151/article/details/131163485