Map
Interaction: Left-click and drag to pan, right-click to change the perspective (tilt/rotate).
TIP
When displaying text on the map, be sure to set the glyphs
property.
TIP
If you need to customize the coordinate system, the crs
parameter format is string or array: [name, wkt, extent]
;
name
: The name of the coordinate system (required).wkt
: The WKT (Well-Known Text) or Proj4 representation of the coordinate system (required).extent
: The extent of the current coordinate system,[left, bottom, right, top]
.
Basic
center:[ 116.3466, 39.8704 ] zoom:8
bearing:0 pitch:0
mouse position:
Example Source Code
<template>
<div style="height: 500px" class="vw-full vh-full">
<div style="height: 400px">
<mb-map
ref="mapInst"
v-model:zoom="mapZoom"
v-model:center="mapCenter"
v-model:bearing="bearing"
v-model:pitch="pitch"
@mousemove="mouseMoveHandler"
>
<div style="position: absolute; top: 10px; left: 10px">
<button class="primary mr10" @click="easeToRandomPos">
ease to some position
</button>
<button class="primary" @click="flyToRandomPos">
fly to some position
</button>
</div>
<mb-tianditu-layer />
</mb-map>
<div style="height: 60px; margin: 10px 0px">
<p class="text-muted">center:{{ mapCenter }} zoom:{{ mapZoom }}</p>
<p class="text-muted">bearing:{{ bearing }} pitch:{{ pitch }}</p>
<p class="text-muted">mouse position:{{ mousePosition }}</p>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { MapInstance } from '@mapbox-vue3/core'
const mapInst = ref<MapInstance>()
const mapCenter = ref([116.3466, 39.8704])
const mapZoom = ref(8)
const bearing = ref(0)
const pitch = ref(0)
const mousePosition = ref('')
const mouseMoveHandler = (movement) => {
mousePosition.value = movement.coordinates
}
const easeToRandomPos = () => {
mapInst.value
?.easeTo({
center: [
mapCenter.value[0] + getRandomArbitrary(-1, 1),
mapCenter.value[1] + getRandomArbitrary(-1, 1),
],
duration: 2000,
})
.then(() => {
// callback after over
})
}
const flyToRandomPos = () => {
mapInst.value
?.flyTo({
center: [getRandomArbitrary(-180, 180), getRandomArbitrary(-90, 90)],
zoom: getRandomArbitrary(0, 18),
})
.then(() => {
// callback after over
})
}
function getRandomArbitrary(min: number, max: number) {
return Math.random() * (max - min) + min
}
</script>
Layer Reordering
Example Source Code
<template>
<div style="height: 500px" class="vw-full vh-full">
<div style="height: 400px">
<mb-map ref="mapInst" :zoom="mapZoom" :center="mapCenter">
<mb-image-loader :images="images" />
<mb-image-frame-loader :images="images2" />
<div style="position: absolute; top: 10px; left: 10px">
<button
class="primary mr10"
@click="reorder(['buffer2', 's3', 'buffer1', 's2', 's1'])"
>
Order:buffer2, s3, buffer1, s2, s1(top)
</button>
<button
class="primary"
@click="reorder(['s2', 's3', 's1', 'buffer2', 'buffer1'])"
>
Order:s2, s3, s1, buffer2, buffer1(top)
</button>
</div>
<mb-tianditu-layer />
<mb-symbol-layer
id="s1"
:data="symbolDataSource"
text-field="label"
icon-image-field="icon"
:icon-size="0.5"
:text-offset="[0, -1]"
icon-allow-overlap
text-allow-overlap
/>
<mb-buffer-ellipse-layer
id="buffer1"
:center="mapCenter"
:x-semi-axis="10"
:y-semi-axis="5"
:angle="0"
border-color="red"
:border-opacity="0.5"
background-color="red"
center-color="red"
center-radius="6"
resizer-color="green"
resizer-radius="6"
rotater-color="black"
:background-opacity="0.1"
:closable="true"
:countable="true"
:draggable="true"
:resizable="true"
:rotatable="true"
/>
<mb-symbol-layer
id="s2"
:data="symbolDataSource2"
text-field="label"
icon-image-field="icon"
:icon-size="0.5"
:text-offset="[0, -1]"
:cluster="true"
:spiderify="true"
:cluster-mamb-zoom="18"
icon-allow-overlap
text-allow-overlap
/>
<mb-symbol-layer
id="s3"
:data="symbolDataSource3"
text-field="label"
icon-image-field="icon"
:icon-size="0.5"
:text-offset="[0, -1]"
icon-allow-overlap
text-allow-overlap
/>
<mb-buffer-sector-layer
id="buffer2"
:polygon="polygon"
:radius="7"
:center="mapCenter"
border-color="red"
:border-opacity="0.5"
background-color="red"
center-color="red"
resizer-color="blue"
:background-opacity="0.1"
:closable="true"
:countable="true"
:draggable="true"
:resizable="true"
:rotatable="true"
/>
</mb-map>
</div>
</div>
</template>
<script setup lang="ts">
import { onBeforeMount, ref } from 'vue'
import type { MapInstance } from '@mapbox-vue3/core/es'
type SymbolLayerData = Array<{
coordinates: number[]
properties?: Record<string, any>
}>
const mapInst = ref<MapInstance>()
const mapCenter = ref([116.3466, 39.8704])
const mapZoom = ref(10)
const symbolDataSource = ref<SymbolLayerData>([])
const symbolDataSource2 = ref<SymbolLayerData>([])
const symbolDataSource3 = ref<SymbolLayerData>([])
const polygon = [
[116.17381, 39.92155464],
[116.25105956968257, 40.02398993628292],
[116.31591012802686, 39.96769599504311],
]
const images = [
{
name: 'event',
type: 'link',
url: `${__RESOURCE_URL__}images/common_toget.png`,
},
{
name: 'event2',
type: 'link',
url: `${__RESOURCE_URL__}images/eme_team_soc_toget.png`,
},
]
const images2 = [
{
name: 'event3',
dir: 'v',
steps: 3,
duration: 300,
url: `${__RESOURCE_URL__}images/v-steps.png`,
},
]
const reorder = (layerIds: string[]) => {
mapInst.value?.reorderLayers(layerIds)
}
onBeforeMount(() => {
symbolDataSource.value = [
{
coordinates: [116.45346681596038, 39.90085772830014],
properties: {
icon: 'event',
},
},
{
coordinates: [...mapCenter.value],
properties: {
icon: 'event',
},
},
]
symbolDataSource2.value = [
{
coordinates: [116.46346681596, 39.90085772830014],
properties: {
icon: 'event2',
},
},
{
coordinates: [...mapCenter.value],
properties: {
icon: 'event2',
},
},
]
symbolDataSource3.value = [
{
coordinates: [116.47346681596038, 39.94085772830014],
properties: {
icon: 'event3',
iconSize: 0.1,
},
},
{
coordinates: [...mapCenter.value],
properties: {
icon: 'event3',
iconSize: 0.1,
},
},
]
})
</script>
Obtaining the Map Instance
Generally, you can obtain the MbMap
instance using a ref
. You can obtain the encapsulated mapbox
instance by listening to the created
event of MbMap
.
- If your component can be placed inside the
MbMap
component, you can use theuseMapCreated
hook provided by the component library to get the map instance.
demo3.vue
<template>
<div style="height: 400px" class="vw-full vh-full">
<mb-map>
<instance1 />
</mb-map>
</div>
</template>
<script setup lang="ts">
import Instance1 from './instance1.vue'
</script>
instance1.vue
<script lang="ts" setup>
import { useMapCreated } from '@mapbox-vue3/core'
const init = () => {
const map = getMapInstance()
const mapbox = getMapboxInstance()
console.log(map, mapbox)
}
const { getMapInstance, getMapboxInstance } = useMapCreated(init)
</script>
- If you want to interact with the map in other components, such as manipulating ThreeJS, you can declare a global variable, then listen to the
created
event and store the Mapbox map instance. Use this instance to operate the map when needed. Below is a partial code example:
// use-map.ts
import type { MapboxInstance } from '@mapbox-vue3/core'
let mapbox: MapboxInstance
function useMap() {
const onCreated = (mb: MapboxInstance) => {
console.log('map created', mb)
mapbox = mb
}
// Remember to destroy when no longer needed
const destroy = () => {
mapbox = null
}
return {
onCreated,
destroy,
// It's important to write this as a method. Directly returning `mapbox` will always result in `undefined`
getMapbox: () => mapbox
}
}
export { useMap }
<template>
<MbMap
...
@created="onCreated"
/>
</template>
<script setup lang="ts">
import { useMap } from './use-map'
const { onCreated } = useMap()
</script>
In the place where you need to use it:
<script lang="ts">
import { useMap } from './use-map'
const { getMapbox } = useMap()
</script>
The above method has a problem: you can only use the getMapbox
method to get the instance after the map instance is created. Otherwise, the obtained instance will be undefined
.
- If your code logic cannot determine whether the map has finished creating when operating the map, you need to use a slightly more complex method for map operations. Below is a code example:
You need to install the ts-deferred
utility library:
// map-deferred.ts
import { Deferred } from 'ts-deferred';
const defferedMap = new Deferred<void>();
const waitingForMap = async() => {
return await defferedMap.promise;
};
const resolveMap = () => {
defferedMap.resolve();
};
export { waitingForMap, resolveMap };
// use-map.ts
import { resolveMap } from './map-deferred'
import type { MapboxInstance } from '@mapbox-vue3/core'
let mapbox: MapboxInstance
function useMap() {
const onCreated = (mb: MapboxInstance) => {
console.log('map created', mb)
mapbox = mb
resolveMap()
}
// Remember to destroy when no longer needed
const destroy = () => {
mapbox = null
}
return {
onCreated,
destroy,
// It's important to write this as a method. Directly returning `mapbox` will always result in `undefined`
getMapbox: () => mapbox
}
}
export { useMap }
// instance.vue
<script lang="ts" setup>
import { onMounted } from 'vue'
import { useMap } from './use-map'
import { waitingForMap } from './map-deferred'
const { getMapbox } = useMap()
onMounted(async() => {
await waitingForMap()
// Now you can use getMapbox() to get the map instance for operations
console.log('operate', getMapbox())
})
</script>
<template>
<MbMap
...
@created="onCreated"
/>
<instance />
</template>
<script setup lang="ts">
import { useMap } from './use-map'
import Instance from './instance.vue'
const { onCreated } = useMap()
</script>
API
PROPS
Name | Description | Type | Default |
---|---|---|---|
antialias | Whether to enable antialiasing; disabling it can improve performance | boolean | true |
bearing | v-model The initial bearing (rotation angle) of the map | number | 0 |
bounds | The initial bounding box of the map. If bounds is set, it will override the center and zoom settings. Its value is the southwest and northeast points of a rectangle, for example: [[-73.9876, 40.7661], [-73.9397, 40.8002]] | IndexAny / AnyArr | undefined |
center | v-model The geographic center point of the map, using the order of longitude, latitude | number[] | [116.38745, 39.91266] |
map-style | Map style information, including font file paths and sprite image paths | IndexAny / string | { version: 8, sources: {}, layers: [], glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf', sprite: "mapbox://sprites/mapbox/bright-v8" } |
glyphs | Path to the font files. Can be set separately and will override the value in mapStyle | string | - |
sprite | Path to the sprite image. Can be set separately and will override the value in mapStyle | string | - |
max-bounds | After being set, the map will be restricted to the given maximum bounds | IndexAny / AnyArr | undefined |
maxzoom | Maximum zoom level of the map | number | 22 |
minzoom | Minimum zoom level of the map | number | 0 |
pitch | v-model The initial pitch of the map | number | 0 |
zoom | v-model The zoom level of the map | number | 2 |
hash | Whether the map's location information is synchronized to the browser URL hash | boolean / string | false |
interactive | Whether the map is interactive | boolean | true |
crs | Coordinate Reference System, with lower priority than extendProps | string / AnyArr | - |
extend-props | Extended properties. See the Mapbox documentation | IndexAny | {} |
extendProps Explanation
All parameters of the Mapbox official documentation's map creation interface can be passed through this property. It has higher priority than all other properties in the Map component.
TIP
Except for the four properties that can be used with v-model
, all other properties are non-reactive. If you need to modify them, you can get the map object through the created
event parameter and then call the Mapbox native API.
EVENTS
名称 | 描述 | 参数 |
---|---|---|
created | Event triggered when the map is initialized | map: MapboxInstance |
update:zoom | Event triggered when the map's zoom level changes | number |
update:center | Event triggered when the map's center changes | number[] |
update:bearing | Event triggered when the map's bearing changes | number |
update:pitch | Event triggered when the map's pitch changes | number |
click | Mouse click event. Triggered on every click | object — Contains screen coordinates pixel , latitude/longitude coordinate , and originalEvent |
dblclick | Mouse double-click event | object — Contains screen coordinates pixel , latitude/longitude coordinate , and originalEvent |
singleclick | Mouse single-click event | object — Contains screen coordinates pixel , latitude/longitude coordinate , and originalEvent |
mousemove | Mouse move event | object — Contains screen coordinates pixel , latitude/longitude coordinate , and originalEvent |
mouseout | Mouse leaves the map area | MapMouseEvent & EventData |
SLOTS
Name | Description |
---|---|
default | Default slot |
METHODS
Name | Description | Definition |
---|---|---|
moveLayer | Moves a layer to a position before the layer represented by beforeId . If beforeId is empty, the layer is moved to the end of the layer list (the top layer of the map) | id: string, beforeId: string | undefined |
resize | Resizes the map according to the dimensions of its container element | - |
setCenter | Sets the center point of the map | centerValue: number[] — longitude/latitude array |
jumpTo | Changes the center point, zoom level, bearing, and pitch without animation. The map will retain the current values for any options not specified | options: object{center, zoom, bearing, pitch} |
easeTo | Changes the center point, zoom level, bearing, and pitch to new values using smooth animation. The map will retain the current values for any options not specified | options: object{center, zoom, bearing, pitch, duration = 1000, easing, offset} => promise |
flyTo | Moves the map to a target location following a flight curve | options: object{center, zoom, bearing, pitch, duration, easing, offset, animate, curve=1.42, speed=1.2, maxDuration} => promise |
stop | Stops all map panning/flying animations | - |
cameraForBounds | Calculates and returns the corresponding camera parameters based on the target bounding box | bounds: number[] — The bounding box, with southwest and northeast points as its values, for example:[[-73.9876, 40.7661], [-73.9397, 40.8002]], options: object{padding,offset=[0,0]} |
fitBounds | Pans and zooms the map to fit the specified geographical bounds within its visible area | bounds: number[] — The bounding box, with southwest and northeast points as its values, for example:[[-73.9876, 40.7661], [-73.9397, 40.8002]], options: object{padding,linear=false,offset=[0,0]} |
project | Returns a Point representing the pixel coordinates relative to the map's container, corresponding to the specified geographical location | lnglatLike |
reorderLayers | Reorders the layers. The parameter is an array of layer IDs | string[] |