Mapbox 控件
本文相关全部代码在mapbox/ch02目录。
控件(Controls)是Mapbox中用于在地图上显示和操作各种元素和工具的组件。它们提供了一种简便的方式来添加额外的功能和交互性,以增强地图应用的用户体验。
Mapbox提供了多种控件,可以根据需求选择并添加到地图上。下面是Mapbox中一些常见的控件:
- 鹰眼图(Overview Map):显示一个小地图视图,可用于快速查看整个地图区域,并提供了导航功能。
- 比例尺控件(Scale Control):用于在地图界面上显示当前地图视图的比例尺
- 全屏控件(Fullscreen Control):用于将地图切换到全屏模式,以占据整个屏幕的可用空间。
- 底图切换控件(Map Style Control):允许用户切换地图的底图样式,例如从街道地图切换到卫星地图。
- 修改切片图层透明度(Opacity Control):允许用户通过调整滑块来控制切片图层的透明度。
- 图例控件(Legend Control):用于显示地图中各个图层的符号图例和说明,以帮助用户理解地图数据和图层含义。
- 信息窗控件(Infobox Control):显示地图上选定要素的信息窗口,可用于显示更详细的数据或与要素交互。
- 地理编码控件(Geocoder Control):提供地理编码和地点搜索功能,使用户能够根据地名或地址查找特定位置。
- 地图导出控件(Export Map Control):允许用户将地图导出为图片或静态图形文件,以便在其他应用程序或文档中使用。
- 绘制和编辑控件(Draw and Edit Controls):允许用户在地图上绘制图形和要素,并提供编辑功能来修改已有的要素。
- 导航控件(Navigation Control):提供地图导航功能,包括平移、缩放和旋转地图视图。
- 测距控件(Distance Measurement Control):允许用户在地图上测量距离,并显示测量结果。
在Mapbox中,可以使用map.addControl方法来添加控件到地图上,使用map.removeControl方法来移除已添加的控件。
添加控件的一般语法为:
map.addControl(controlInstance, position);
其中,controlInstance是控件的实例对象,position是控件在地图上的位置,可以是一个字符串或一个DOM元素。位置参数用于指定控件在地图中的放置位置,例如:"top-left"、"top-right"、"bottom-left"、"bottom-right"等。
移除控件的语法为:
map.removeControl(controlInstance);
其中,controlInstance是要移除的控件实例对象。
通过使用map.addControl和map.removeControl方法,可以根据需要在地图上动态添加和移除不同的控件,以满足地图应用的需求。
请注意,具体控件的添加和移除方法可能会有所不同,具体的用法和参数设置请参考Mapbox的官方文档和相关示例。
鹰眼图
鹰眼图控件(Overview Map Control)是一个用于在地图界面上显示一个小型的鹰眼图窗口的功能,用于提供对整个地图范围的概览。尽管 Mapbox 官方没有直接提供鹰眼图控件,但可以通过编码实现该功能。实现鹰眼图控件的基本思路如下:
- 在原始地图上添加一个用于承载鹰眼图缩略图的小窗口。
- 在鹰眼图窗口中绘制一个面(矩形),该面会遮盖当前主视图中所查看的范围。
- 当原始地图发生放大、缩小或平移操作时,鹰眼图窗口中的遮盖面会同步移动。
下面是实现鹰眼图控件的示例代码:
initOverMap(map) {
let ovmap = new mapboxgl.Map({
container: "overview",
style: "mapbox://styles/mapbox/streets-v11",
center: [120, 30],
zoom: map.getZoom() - 4 // starting zoom
});
let map_x; //地图的x坐标
let map_y; //地图的y坐标
let overview_x; //鹰眼的x坐标
let overview_y; //鹰眼的y坐标
let map_zoom; //地图的比例尺
let overview_zoom; //鹰眼的比例尺
function convertBoundsToPoints(bounds) {
let ne = bounds._ne;
let sw = bounds._sw;
let trc = [[[], [], [], [], []]];
trc[0][0][0] = ne.lng;
trc[0][0][1] = ne.lat;
trc[0][1][0] = sw.lng;
trc[0][1][1] = ne.lat;
trc[0][2][0] = sw.lng;
trc[0][2][1] = sw.lat;
trc[0][3][0] = ne.lng;
trc[0][3][1] = sw.lat;
trc[0][4][0] = ne.lng;
trc[0][4][1] = ne.lat;
return trc;
}
function changeGeojson() {
let coods = convertBoundsToPoints(map.getBounds())
let geojson = {
"type": "Feature",
"properties": {
"name": "trackingRect"
},
"geometry": {
"type": "Polygon",
"coordinates": coods,
}
}
ovmap.getSource("trackingRect").setData(geojson)
}
// 拖拽
function mapDrag() {
map_x = map.getCenter().lng;
map_y = map.getCenter().lat;
console.log("拖拽")
console.log(ovmap.getSource("trackingRect"));
changeGeojson();
ovmap.setCenter([map_x, map_y]);
}
function overviewDrag() {
overview_x = ovmap.getCenter().lng;
overview_y = ovmap.getCenter().lat;
changeGeojson();
map.setCenter([overview_x, overview_y]);
}
// 放大缩小
function mapZoom() {
map_zoom = map.getZoom();
changeGeojson();
ovmap.setZoom(map_zoom - 4);
}
function overviewZoom() {
overview_zoom = ovmap.getZoom();
changeGeojson();
map.setZoom(overview_zoom + 4);
}
ovmap.on("load", function () {
let coods = convertBoundsToPoints(map.getBounds())
let geojson = {
"type": "geojson",
"data": {
"type": "Feature",
"properties": {
"name": "trackingRect"
},
"geometry": {
"type": "Polygon",
"coordinates": coods,
}
}
}
ovmap.addSource("trackingRect", geojson)
ovmap.addLayer({
"id": "trackingRectOutline",
"type": "line",
"source": "trackingRect",
"layout": {},
"paint": {
"line-color": "#08f",
"line-width": 2,
"line-opacity": 1
}
});
// needed for dragging
ovmap.addLayer({
"id": "trackingRectFill",
"type": "fill",
"source": "trackingRect",
"layout": {},
"paint": {
"fill-color": "#f80",
"fill-opacity": 0.25
}
});
})
map.on("drag", mapDrag);
map.on("zoom", mapZoom);
let overview = document.getElementById("overview");
overview.addEventListener("mouseover", function () {
//移除地图的拖拽监听
map.off("drag", mapDrag);
map.off("zoom", mapZoom);
//添加鹰眼的拖拽监听
ovmap.on("drag", overviewDrag);
ovmap.on("zoom", overviewZoom);
});
overview.addEventListener("mouseout", function () {
//添加地图的拖拽监听
map.on("drag", mapDrag);
map.on("zoom", mapZoom);
//移除鹰眼的拖拽监听
ovmap.off("drag", overviewDrag);
ovmap.off("zoom", overviewZoom);
});
}
在上述代码中,通过initOverMap函数来初始化鹰眼图控件。在该函数中,创建了一个新的地图实例 ovmap,用于显示鹰眼图。设置了地图的容器 container,地图样式 style,地图的中心点 center(示例中为 [120, 30]),以及地图的初始缩放级别 zoom(通过减去 4 来保持适当的缩放级别)。
然后,定义了一些变量用于存储地图和鹰眼图的中心点经纬度以及缩放级别。还实现了一些功能函数,例如 convertBoundsToPoints 函数用于将地图的边界转换为坐标点数组,changeGeojson 函数用于更新鹰眼图上的遮盖面。
在鹰眼图的 load 事件中,添加了用于绘制鹰眼图上遮盖面的图层。使用 convertBoundsToPoints 函数获取当前地图的边界的坐标点数组,并将其作为 GeoJSON 数据设置给鹰眼图的 trackingRect 数据源。
接下来,通过事件监听的方式将原始地图的拖拽和缩放操作与鹰眼图的拖拽和缩放操作进行关联。当鼠标悬停在鹰眼图上时,移除原始地图的拖拽和缩放事件监听,并添加鹰眼图的拖拽和缩放事件监听。这样,当在鹰眼图上拖拽或缩放时,原始地图会相应地移动或缩放以保持同步。当鼠标移出鹰眼图时,恢复原始地图的拖拽和缩放事件监听,并移除鹰眼图的拖拽和缩放事件监听。
通过以上代码,成功实现了鹰眼图控件的功能。在地图界面上的鹰眼图窗口中,可以看到一个小的缩略图,该缩略图显示了整个地图范围,并通过遮盖面来标识当前主视图所查看的区域。当在鹰眼图上进行拖拽或缩放操作时,原始地图会相应地进行移动或缩放以保持视图同步。
需要注意,在使用本鹰眼图时需要注意等原地图和鹰眼图都加载完成后再进行操作,否则将会有卡顿或者对象没有初始化完成的情况
具体效果如图所示
比例尺控件
比例尺控件(Scale Control)是Mapbox中的一个常用控件,用于在地图界面上显示当前地图视图的比例尺。比例尺是一个标尺,用于显示地图上距离和长度的比例关系,帮助用户了解地图上的尺寸和相对距离。添加控件后,控件信息如图所示。
如果需要添比例尺控件可以执行如下代码。
const scale = new mapboxgl.ScaleControl({
maxWidth: 80,
unit: 'metric'
},"bottom-left");
this.map.addControl(scale);
在上述代码中,首先创建了一个mapboxgl.ScaleControl的实例,该实例代表了比例尺控件。在创建实例时,可以通过传递一个选项对象来进行一些配置,具体配置有两项:
maxWidth参数控制比例尺控件的最大宽度(以像素为单位)。默认情况下,最大宽度为100。unit参数控制比例尺的单位。在上述示例中,将单位设置为'metric',表示使用公制单位(如米、千米)。其他可用的单位选项包括'imperial'(英制单位)和'nautical'(海里单位)。
然后,使用map.addControl方法将比例尺控件添加到地图上。通过添加比例尺控件,可以在地图界面上看到当前地图视图的比例尺,并根据需要调整比例尺的显示样式和单位。
如果需要比例尺修改样式可以对.mapboxgl-ctrl.mapboxgl-ctrl-scale类进行调整,示例代码如下。
.mapboxgl-ctrl.mapboxgl-ctrl-scale {
height: 10px;
background-color:transparent;
line-height:10%;
text-align:center
}
调整后样式如图所示
全屏控件
全屏控件(Fullscreen Control)是Mapbox中的一个常用控件,用于将地图切换到全屏模式,以占据整个屏幕的可用空间。通过添加全屏控件,用户可以方便地将地图切换到全屏模式,以获得更大的地图视图。添加控件后,控件信息如图所示。
如果需要添加全屏控件可以执行如下代码。
this.map.addControl(new mapboxgl.FullscreenControl());
在上述代码中,首先创建了一个mapboxgl.FullscreenControl的实例,该实例代表了全屏控件,最后使用map.addControl方法将全屏控件添加到地图上。
通过添加全屏控件,可以在地图界面上看到一个全屏切换按钮,使用户可以方便地将地图切换到全屏模式。这可以提供更大的地图视图,并允许用户更好地浏览和使用地图。
需要注意的是,全屏控件的可用性取决于浏览器的支持。某些浏览器可能限制或阻止全屏模式的使用,因此在使用全屏控件时需要考虑到这些限制。
底图切换控件
底图切换控件(Map Style Control)允许用户在地图中切换不同的底图样式,例如从街道地图切换到卫星地图。添加该控件后,用户可以方便地切换底图,以满足不同的需求和视觉风格。以下是实现底图切换控件的步骤:
- 添加第三方依赖:需要添加名为
mapbox-gl-style-switcher的第三方依赖。可以使用以下命令进行安装:
npm i mapbox-gl-style-switcher --save
2. 导入依赖:在需要添加控件的页面中,导入mapbox-gl-style-switcher的相关依赖。确保在正确的位置引入样式文件以确保控件的正确显示。。以下是示例代码:
import {MapboxStyleSwitcherControl} from "mapbox-gl-style-switcher";
import "mapbox-gl-style-switcher/styles.css";
map.addControl(new MapboxStyleSwitcherControl());
上述代码将添加底图切换控件到地图中。但是,默认情况下,控件显示的是英文选项。效果如图所示
- 修改为中文选项:如果需要将底图切换控件的选项修改为中文,可以根据需求自定义控件的选项。以下是示例代码:
this.map.addControl(new MapboxStyleSwitcherControl(
[
{
title: "街道底图",
uri: "mapbox://styles/mapbox/streets-v12",
},
{
title: "户外底图",
uri: "mapbox://styles/mapbox/outdoors-v12",
},
{
title: "亮色底图",
uri: "mapbox://styles/mapbox/light-v11",
},
{
title: "暗色底图",
uri: "mapbox://styles/mapbox/dark-v11",
},
{
title: "卫星底图",
uri: "mapbox://styles/mapbox/satellite-v9",
},
{
title: "卫星街道混合底图",
uri: "mapbox://styles/mapbox/satellite-streets-v12",
},
{
title: "导航底图(白天)",
uri: "mapbox://styles/mapbox/navigation-day-v1",
},
{
title: "导航底图(晚上)",
uri: "mapbox://styles/mapbox/navigation-night-v1",
}
]
))
修改后的效果如下图所示:
修改切片图层透明度控件
修改切片图层透明度控件(Opacity Control)允许用户通过调整滑块来控制切片图层的透明度。这个控件主要适用于栅格数据的展示,例如地图底图。通过使用该控件,用户可以灵活地调整底图的透明度,以满足不同的需求。以下是实现底图切换控件的步骤:
- 添加第三方依赖:需要添加名为
mapbox-gl-opacity的第三方依赖。可以使用以下命令进行安装。
npm i mapbox-gl-opacity
2. 导入依赖:在需要添加控件的页面中,导入mapbox-gl-opacity的相关依赖。确保在正确的位置引入样式文件以确保控件的正确显示。
import OpacityControl from "mapbox-gl-opacity";
import "mapbox-gl-opacity/src/mapbox-gl-opacity.css";
- 添加控件:在地图加载完成后,创建一个控件实例,并将其添加到地图中。控件的配置可以包括基础图层和覆盖图层的设置,以及控制透明度的选项。具体代码如下。
initmap() {
mapboxgl.accessToken =
"pk.eyJ1IjoiemVuc2FuIiwiYSI6ImNsandiMWx4djFsd3MzY3RodG1vNm55bm4ifQ.DpwvbO12Bli7Cbok5mMU7Q";
this.map = new mapboxgl.Map({
container: this.$refs.map,
style: {
version: 8,
sources: {
m_mono: {
type: "raster",
tiles: ["https://tile.mierune.co.jp/mierune_mono/{z}/{x}/{y}.png"],
tileSize: 256,
}
},
layers: [{
id: "m_mono",
type: "raster",
source: "m_mono",
minzoom: 0,
maxzoom: 18
}]
},
center: [139.7670, 35.6810],
zoom: 10
});
this.map.on("load",()=>{
this.map.addSource("m_color", {
type: "raster",
tiles: ["https://tile.mierune.co.jp/mierune/{z}/{x}/{y}.png"],
tileSize: 256
});
this.map.addLayer({
id: "m_color",
type: "raster",
source: "m_color",
minzoom: 0,
maxzoom: 18
});
this.map.addSource("o_std", {
type: "raster",
tiles: [
"https://a.tile.openstreetmap.org/{z}/{x}/{y}.png",
"https://b.tile.openstreetmap.org/{z}/{x}/{y}.png"
],
tileSize: 256
});
this.map.addLayer({
id: "o_std",
type: "raster",
source: "o_std",
minzoom: 0,
maxzoom: 18
});
this.map.addSource("t_pale", {
type: "raster",
tiles: ["https://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png"],
tileSize: 256
});
this.map.addLayer({
id: "t_pale",
type: "raster",
source: "t_pale",
minzoom: 0,
maxzoom: 18
});
this.map.addSource("t_ort", {
type: "raster",
tiles: ["https://cyberjapandata.gsi.go.jp/xyz/ort/{z}/{x}/{y}.jpg"],
tileSize: 256
});
this.map.addLayer({
id: "t_ort",
type: "raster",
source: "t_ort",
minzoom: 0,
maxzoom: 18
});
const mapBaseLayer = {
m_mono: "单色",
m_color: "彩色"
};
const mapOverLayer = {
o_std: "开源街道地图样式",
t_pale: "浅色调地图样式",
t_ort: "正射影像地图样式"
};
let Opacity = new OpacityControl({
baseLayers: mapBaseLayer,
overLayers: mapOverLayer,
opacityControl: true
});
this.map.addControl(Opacity, 'top-right');
})
}
通过以上步骤,修改切片图层透明度控件将成功添加到地图中。用户可以通过控制滑块来调整切片图层的透明度,实现灵活的地图展示效果,具体效果如图所示。
图例控件
图例控件(Legend Control)允许用户在地图上显示与图层相关的图例信息以下是实现底图切换控件的步骤:
- 添加第三方依赖:需要添加名为
@watergis/mapbox-gl-legend的第三方依赖。可以使用以下命令进行安装:
npm i @watergis/mapbox-gl-legend --save
- 导入依赖:在需要添加控件的页面中,导入
@watergis/mapbox-gl-legend的相关依赖。确保在正确的位置引入样式文件以确保控件的正确显示。
import { MapboxLegendControl } from "@watergis/mapbox-gl-legend";
import '@watergis/mapbox-gl-legend/css/styles.css';
- 添加控件:在地图加载完成后,创建一个控件实例,并将其添加到地图中。控件的配置可以包括基础图层和覆盖图层的设置,以及控制透明度的选项。具体代码如下
this.map.on("load",()=>{
let coods =[
[
[
120.1455417593927,
30.30902958750555
],
[
120.1455417593927,
30.123904173718486
],
[
120.38174781407992,
30.123904173718486
],
[
120.38174781407992,
30.30902958750555
],
[
120.1455417593927,
30.30902958750555
]
]
]
let geojson = {
"type": "geojson",
"data": {
"type": "Feature",
"properties": {
"name": "trackingRect"
},
"geometry": {
"type": "Polygon",
"coordinates": coods,
}
}
}
this.map.addSource("trackingRect", geojson)
this.map.addLayer({
"id": "trackingRectOutline",
"type": "line",
"source": "trackingRect",
"layout": {},
"paint": {
"line-color": "#08f",
"line-width": 2,
"line-opacity": 1
}
});
this.map.addLayer({
"id": "trackingRectFill",
"type": "fill",
"source": "trackingRect",
"layout": {},
"paint": {
"fill-color": "#f80",
"fill-opacity": 0.25
}
});
const targets = {
trackingRectFill: '面',
trackingRectOutline: '包围线',
};
this.map.addControl(new MapboxLegendControl(targets, {
showDefault: true,
showCheckbox: true,
onlyRendered: true,
reverseOrder: true,
accesstoken:mapboxgl.accessToken,
}), 'top-right');
})
options参数说明:
showDefault:是否默认显示图例。true:默认显示图例。false:默认隐藏图例。- 默认值是
true。
showCheckbox:是否默认显示切换可见性的复选框。true:默认显示切换可见性的复选框。false:默认不显示切换可见性的复选框。- 默认值是
true。
reverseOrder:图例项的顺序。true:从顶部开始排序图例项。false:从底部开始排序图例项。- 默认值是
true。
onlyRendered:是否只显示已渲染图层的图例。true:只显示已渲染图层的图例。false:显示所有图层的图例。- 默认值是
true。
需要注意,图例控件的显示与图层的样式相关。当使用map.addLayer方法添加图层后,该图层将被自动添加到图例控件的候选池中。因此,确保targets参数中的键与map.addLayer中设置的图层ID相对应,否则图例控件无法正确渲染。在本例中trackingRectFill和trackingRectOutline是通过map.addLayer方法添加的图层的ID,而'面'和'包围线'是要显示在图例控件上的对应内容。请确保在使用图例控件时,targets参数中的键与map.addLayer方法中设置的图层ID完全匹配,这样才能正常渲染图例信息。
具体效果如图所示。
信息窗控件
信息窗控件(Infobox Control):显示地图上选定要素的信息窗口,可用于显示更详细的数据或与要素交互。以下是实现信息窗控件的步骤:
- 添加第三方依赖:需要添加名为
mapbox-gl-infobox的第三方依赖。可以使用以下命令进行安装:
npm i mapbox-gl-infobox --save
- 导入依赖:在需要添加控件的页面中,导入
mapbox-gl-infobox的相关依赖。确保在正确的位置引入样式文件以确保控件的正确显示。
import "mapbox-gl-infobox/styles.css";
import { MapboxGradientBoxControl, MapboxInfoBoxControl } from "mapbox-gl-infobox";
- 添加控件:在地图加载完成后,创建信息窗控件的实例,并将其添加到地图中。具体代码如下:
initmap() {
mapboxgl.accessToken =
"pk.eyJ1IjoiemVuc2FuIiwiYSI6ImNsandiMWx4djFsd3MzY3RodG1vNm55bm4ifQ.DpwvbO12Bli7Cbok5mMU7Q";
this.map = new mapboxgl.Map({
container: this.$refs.map,
style: "mapbox://styles/mapbox/streets-v11",
center: [
120.1455417593927,
30.30902958750555
],
zoom: 12,
});
this.map.on("load",()=>{
let coods =[
[
[
120.1455417593927,
30.30902958750555
],
[
120.1455417593927,
30.123904173718486
],
[
120.38174781407992,
30.123904173718486
],
[
120.38174781407992,
30.30902958750555
],
[
120.1455417593927,
30.30902958750555
]
]
]
let geojson = {
"type": "geojson",
"data": {
"type": "Feature",
"properties": {
"name": "测试面",
"weight":30
},
"geometry": {
"type": "Polygon",
"coordinates": coods,
}
}
}
this.map.addSource("trackingRect", geojson)
this.map.addLayer({
"id": "trackingRectFill",
"type": "fill",
"source": "trackingRect",
"layout": {},
"paint": {
"fill-color": "#f80",
"fill-opacity": 0.25
}
});
})
const layerId = "trackingRectFill";
const minMaxValues = {minValue: 0, maxValue: 100};
const weightGetter = properties => properties ? properties['weight'] : 0;
const gradientOptions = {
layerId,
minMaxValues,
weightGetter
};
this.map.addControl(new MapboxGradientBoxControl(gradientOptions));
const formatter = properties => properties ? `<b>名称:</b> ${properties['name']}` : '';
const infoboxOptions = {
layerId,
formatter
};
this.map.addControl(new MapboxInfoBoxControl(infoboxOptions));
}
在这个示例中使用了两个不同的控件:渐变框控件(MapboxGradientBoxControl)和信息窗控件(MapboxInfoBoxControl)。
-
渐变框控件(MapboxGradientBoxControl)。
layerId:指定要应用渐变框控件的图层ID。minMaxValues:指定渐变框控件中权重(weight)的最小值和最大值。这里设置的最小值为0,最大值为100。weightGetter:是一个函数,用于获取要素属性中的权重值。在这个示例中,使用properties['weight']来获取要素的权重值。
使用上述参数,创建了一个
gradientOptions对象,包含了渐变框控件的配置信息。然后,通过new MapboxGradientBoxControl(gradientOptions)创建渐变框控件的实例,并将其添加到地图中。 -
信息窗控件(MapboxInfoBoxControl)。
layerId:指定要应用信息窗控件的图层ID。formatter:是一个函数,用于根据要素属性格式化信息窗的内容。在这个示例中,使用模板字符串(template string)来构建信息窗的内容,并使用properties['name']来获取要素的名称。
使用上述参数,创建了一个
infoboxOptions对象,包含了信息窗控件的配置信息。最后通过new MapboxInfoBoxControl(infoboxOptions)创建信息窗控件的实例,并将其添加到地图中。
请注意如下两点:
- 需要根据实际需求添加图层,并在图层加载完成后添加信息窗控件。在示例中使用的是名为
trackingRectFill的图层,可以根据项目中图层ID进行相应的调整。 properties对象中的属性名和属性值是根据项目中的地图数据和属性定义而定的。可以根据实际情况修改代码,以便访问正确的属性值,并在信息窗中显示所需的信息。
当鼠标经过橙色面区域时会在左上角显示权重区间和名称内容,具体如图所示。
地理编码控件
地理编码控件(Geocoder Control):提供地理编码和地点搜索功能,使用户能够根据地名或地址查找特定位置。以下是实现地理编码控件的步骤。
- 添加第三方依赖:需要添加名为
@mapbox/mapbox-gl-geocoder的第三方依赖。可以使用以下命令进行安装:
npm install --save @mapbox/mapbox-gl-geocoder
2. 导入依赖:在需要添加控件的页面中,导入@mapbox/mapbox-gl-geocoder的相关依赖。确保在正确的位置引入样式文件以确保控件的正确显示。
import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css';
- 添加控件:在地图加载完成后,创建地理编码控件的实例,并将其添加到地图中。具体代码如下:
const geocoder = new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl
});
this.map.addControl(geocoder)
最终在界面上效果如图所示。
地图导出控件
地图导出控件(Export Map Control):允许用户将地图导出为图片或静态图形文件,以便在其他应用程序或文档中使用。以下是实现地图导出控件的步骤。
- 添加第三方依赖:需要添加名为
@watergis/mapbox-gl-export的第三方依赖。可以使用以下命令进行安装:
npm i @watergis/mapbox-gl-export --save
- 导入依赖:在需要添加控件的页面中,导入
@watergis/mapbox-gl-export的相关依赖。确保在正确的位置引入样式文件以确保控件的正确显示。
import { MapboxExportControl, Size, PageOrientation, Format, DPI} from "@watergis/mapbox-gl-export";
import '@watergis/mapbox-gl-export/css/styles.css';
- 添加控件:在地图加载完成后,创建地图导出控件的实例,并将其添加到地图中。具体代码如下:
this.map.addControl(new MapboxExportControl({
accessToken: mapboxgl.accessToken,
Local: 'zh_Hans_CN'
}), 'top-right')
注意: 由于mapbox-gl-export插件官方没有提供中文内容,需要手工下载仓库将其编译后替换。仓库地址:git@github.com:huifer/mapbox-gl-export.git ,替换方式是删除mapbox/ch02/node_modules/@watergis/mapbox-gl-export目录下的dist文件将编译后的dist文件拷贝到此目录。最终界面如图所示。
绘制和编辑控件
绘制和编辑控件(Draw and Edit Controls):允许用户在地图上绘制图形和要素,并提供编辑功能来修改已有的要素。以下是实现绘制和编辑控件的步骤:
- 添加第三方依赖:需要安装名为
@mapbox/mapbox-gl-draw的第三方依赖,可以使用以下命令进行安装:
npm install @mapbox/mapbox-gl-draw
- 导入依赖:在需要添加绘制和编辑控件的页面中,导入
@mapbox/mapbox-gl-draw的相关依赖。确保正确引入样式文件以确保控件的正确显示。
import MapboxDraw from "@mapbox/mapbox-gl-draw";
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'
- 添加控件:在地图加载完成后,创建绘制和编辑控件的实例,并将其添加到地图中。以下是具体的代码示例:
var Draw = new MapboxDraw({
controls: {
point: true,
line_string: true,
polygon: true,
trash: true
},
displayControlsDefault:false
});
this.map.addControl(Draw, 'top-left')
绘制和编辑控件的参数说明如下:
controls,对象(Object):用于隐藏或显示各个控件的属性。每个属性的名称是一个控件,对应的值是一个布尔值,用于指示控件是否显示。可用的控件名称包括point(点)、line_string(线)、polygon(面)、trash(删除)、combine_features(合并要素)和uncombine_features(拆分要素)。默认情况下,所有的控件都是开启的。如果想要更改默认设置,可以使用displayControlsDefault。displayControlsDefault,布尔值(boolean)(默认值:true):控件的默认设置。例如,如果希望默认情况下所有的控件都是关闭的,并且通过controls指定一个允许显示的控件列表,可以将displayControlsDefault设置为false。
效果如图所示
在绘制和编辑控件中还涉及到事件相关的内容,主要关注如下几个事件
draw.create:当创建要素时触发的事件。通过监听该事件,可以在要素创建完成后执行相应的操作。示例代码如下:
this.map.on("draw.create",(e)=>{
console.log("绘制完成", e);
})
上述代码中,e对象包含了有关已创建要素的相关信息。在控制台输出的内容中,最关键的属性是e.features,它包含了与地理数据相关的信息。上述代码输出内容如图所示。
draw.delete:当删除一个或多个要素时触发的事件。通过监听该事件,可以在要素删除后执行相应的操作。示例代码如下:
this.map.on('draw.delete', (e)=>{
console.log("绘制删除",e)
})
上述代码输出内容如图所示。
draw.update:当更新一个或多个要素时触发的事件。通过监听该事件,可以在要素更新后执行相应的操作。示例代码如下:
this.map.on('draw.update', (e)=>{
console.log("绘制修改",e)
})
上述代码输出内容如图所示。
draw.selectionchange:当更改选择(即选择或取消选择一个或多个要素)时触发的事件。示例代码如下:
this.map.on("draw.selectionchange",(e)=>{
console.log("绘制选择",e)
})
上述代码输出内容如图所示。
需要注意的是,draw.selectionchange事件在以下交互中被触发:
- 单击某个要素以选中它。
- 当已选择某个要素时,按住 Shift 键单击另一个要素以将其添加到选择中。
- 单击顶点以选中它。
- 如果已选择顶点,按住 Shift 键单击另一个顶点以将其添加到选择中。
- 完成要素绘制后(要素在创建后立即选中)。
导航控件
在Mapbox中,导航控件(Navigation Control)是一种方便的工具,用于向地图界面添加导航功能。虽然官方定义的导航控件本身并不具备实际的导航能力,但它提供了一些常用的导航操作按钮,如指北针、放大和缩小按钮,以便用户在地图上进行导航操作,添加控件后,控件信息如图所示。

如果需要添导航控件可以执行如下代码。
const nav = new mapboxgl.NavigationControl(
{
visualizePitch: true,
showCompass: true,
showZoom: true,
}
);
this.map.addControl(nav, 'top-left');
在NavigationControl中提供三个参数:
-
visualizePitch(可选):控制指北针在倾斜地图时是否跟随倾斜。默认情况下,指北针不会倾斜。设置为true时,指北针会根据地图的倾斜程度进行相应的旋转。 -
showCompass(可选):指定是否显示指北针按钮。默认情况下,指北针按钮是可见的。 -
showZoom(可选):指定是否显示放大和缩小按钮。默认情况下,放大和缩小按钮是可见的。
测距控件
测距控件(Distance Measurement Control):允许用户在地图上测量距离,并显示测量结果。以下是实现测距控件的步骤:
- 添加第三方依赖:需要安装名为
mapbox-gl-controls的第三方依赖。可以使用以下命令进行安装:
npm install mapbox-gl-controls
- 导入依赖:在需要添加控件的页面中,导入相关依赖,并确保正确引入样式文件。
import "mapbox-gl-controls/lib/controls.css";
import { RulerControl } from 'mapbox-gl-controls';
- 添加控件:在地图加载完成后,创建测距控件的实例,并将其添加到地图中。
this.map.on('ruler.on', () => console.log('ruler: on'));
this.map.on('ruler.off', () => console.log('ruler: off'));
this.map.addControl(new RulerControl({
units: 'miles',
labelFormat: n => `${n.toFixed(2)} ml`,
}), 'top-right');
使用测距控件时,可以根据需求设置以下两个核心参数:
units:用于指定测量结果的单位。可以选择以下候选值之一:- "meters":米
- "millimeters":毫米
- "centimeters":厘米
- "kilometers":千米
- "acres":英亩
- "miles":英里
- "nauticalmiles":海里
- "inches":英寸
- "yards":码
- "feet":英尺
- "radians":弧度
- "degrees":度数
- "hectares":公顷
labelFormat:用于自定义测量结果标签的格式。可以提供一个回调函数来自定义标签的显示方式。回调函数的参数是测量结果的数值,可以对其进行处理并返回自定义的标签字符串。
在mapbox-gl-controls第三方依赖中还包含一个重要的控件,即语言控件(Language Control),用于设置地图的显示语言。通过该控件,可以指定地图的语言,以便在地图上显示相应的标签和文本内容。示例代码如下。
const languageControl = new LanguageControl({
language: 'zh',
});
this.map.addControl(languageControl);
在language参数中,可以根据需要选择以下候选值之一来设置地图的语言:
- 'en': 英语
- 'es': 西班牙语
- 'fr': 法语
- 'de': 德语
- 'ru': 俄语
- 'zh': 中文
- 'pt': 葡萄牙语
- 'ar': 阿拉伯语
- 'ja': 日语
- 'ko': 韩语
- 'mul': 多种语言
总结
Mapbox提供了丰富的控件选项,可以根据需求在地图上添加各种功能和交互元素。这些控件包括鹰眼图、比例尺控件、全屏控件、底图切换控件、修改切片图层透明度、图例控件、信息窗控件、地理编码控件、地图导出控件、绘制和编辑控件、导航控件以及测距控件。
通过这些控件,用户可以实现诸如查看整个地图区域、导航操作、切换地图样式、调整图层透明度、了解比例尺、显示图例、查找地点、绘制和编辑要素、测量距离等功能。这些控件提供了方便的工具和交互方式,使地图使用更加便捷、直观和个性化。
通过选择合适的控件并将其添加到地图中,可以根据实际需求和用户体验来优化地图界面和功能,提升地图的可用性和交互性。无论是在展示地理数据、导航应用、位置分析还是其他地图相关应用中,Mapbox的控件选项能够满足各种需求,并为用户提供出色的地图体验。