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
Example Source Code
import React, { useRef, useState } from 'react'
import ReactDOM from 'react-dom'
import { MbMap, MbWmtsLayer } from '@mapbox-react/core'
const App = () => {
const [mapCenter] = useState([116.3466, 39.8704])
const [zoom, setZoom] = useState(8)
const [pitch, setPitch] = useState(0)
const mapInst = useRef<any>()
const [mousePosition, setMousePosition] = useState('')
const easeToRandomPos = () => {
mapInst.current
?.easeTo({
center: [
mapCenter[0] + getRandomArbitrary(-1, 1),
mapCenter[1] + getRandomArbitrary(-1, 1),
],
duration: 2000,
})
.then(() => {
// callback after over
})
}
const flyToRandomPos = () => {
mapInst.current
?.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
}
const mouseMoveHandler = (movement) => {
setMousePosition(movement.coordinates)
}
return (
<div className="map-wrapper">
<MbMap
ref={mapInst}
center={mapCenter}
zoom={zoom}
pitch={pitch}
crs="EPSG:3857"
extendProps={{
accessToken:
'pk.eyJ1IjoiYml0ampqIiwiYSI6ImNtMnNubnlyNTFvNnoycHB5M2M2ZjVpeHEifQ.kk7T4f-CuUA_K6AuPwbvMg',
}}
onMouseMove={mouseMoveHandler}
onZoomChange={(z) => setZoom(z)}
onPitchChange={(p) => setPitch(p)}
>
<div style={{ position: 'absolute', top: '10px', left: '10px' }}>
<button className="primary mr10" onClick={easeToRandomPos}>
ease to some position
</button>
<button className="primary" onClick={flyToRandomPos}>
fly to some position
</button>
</div>
<MbWmtsLayer
url="https://t{s}.tianditu.gov.cn/img_w/wmts?tk=b8ed92ff9b64aebcb0110acca15e478f"
layerName="img"
layerStyle="default"
tileMatrixSetID="w"
subdomains="01234567"
maxzoom={18}
/>
</MbMap>
<div
style={{
position: 'absolute',
bottom: '0px',
right: '0px',
backgroundColor: 'white',
padding: '10px',
}}
>
<p className="text-muted">
center:{`${mapCenter}`} zoom:{zoom}
</p>
<p className="text-muted">pitch:{`${pitch}`}</p>
<p className="text-muted">mouse position:{`${mousePosition}`}</p>
</div>
</div>
)
}
ReactDOM.render(<App />, document.querySelector('#root'))
Layer Reordering
Example Source Code
import React, { useState, useRef } from 'react'
import ReactDOM from 'react-dom'
import { MbMap, MbTiandituLayer, MbImageLoader, MbImageFrameLoader, MbSymbolLayer, MbBufferEllipseLayer, MbBufferPolygonLayer } from '@mapbox-react/core'
const App = () => {
const [mapCenter] = useState([116.3466, 39.8704])
const [zoom, setZoom] = useState(10)
const mapInst = useRef<any>()
const symbolDataSource = [
{
coordinates: [116.45346681596038, 39.90085772830014],
properties: {
icon: 'event',
},
},
{
coordinates: [...mapCenter],
properties: {
icon: 'event',
},
},
]
const symbolDataSource2 = [
{
coordinates: [116.46346681596, 39.90085772830014],
properties: {
icon: 'event2',
},
},
{
coordinates: [...mapCenter],
properties: {
icon: 'event2',
},
},
]
const symbolDataSource3 = [
{
coordinates: [116.47346681596038, 39.94085772830014],
properties: {
icon: 'event3',
iconSize: 0.1,
},
},
{
coordinates: [...mapCenter],
properties: {
icon: 'event3',
iconSize: 0.1,
},
},
]
const polygon = [
[116.17381, 39.92155464],
[116.25105956968257, 40.02398993628292],
[116.31591012802686, 39.96769599504311],
]
const images = [
{
name: 'event',
type: 'link',
url: `https://mapbox-web.github.io/mapbox-react/images/common_toget.png`,
},
{
name: 'event2',
type: 'link',
url: `https://mapbox-web.github.io/mapbox-react/images/eme_team_soc_toget.png`,
},
]
const images2 = [
{
name: 'event3',
dir: 'v' as const,
steps: 3,
duration: 300,
url: `https://mapbox-web.github.io/mapbox-react/images/v-steps.png`,
},
]
const reorder = (layerIds: string[]) => {
mapInst.current?.reorderLayers(layerIds)
}
return (
<div className="map-wrapper">
<MbMap
ref={mapInst}
center={mapCenter}
zoom={zoom}
>
<div style={{ position: 'absolute', top: '10px', left: '10px' }}>
<button onClick={() => reorder(['buffer2', 's3', 'buffer1', 's2', 's1'])}>Order:buffer2, s3, buffer1, s2, s1(top)</button>
<button onClick={() => reorder(['s2', 's3', 's1', 'buffer2', 'buffer1'])}>Order:s2, s3, s1, buffer2, buffer1(top)</button>
</div>
<MbTiandituLayer types={['vec', 'cva']} />
<MbImageLoader images={images} />
<MbImageFrameLoader images={images2} />
<MbSymbolLayer
id="s1"
data={symbolDataSource}
textField="label"
iconImageField="icon"
iconSize={0.5}
textOffset={[0, -1]}
iconAllowOverlap={true}
textAllowOverlap={true}
/>
<MbBufferEllipseLayer
id="buffer1"
center={mapCenter}
xSemiAxis={10}
ySemiAxis={5}
angle={0}
/>
<MbSymbolLayer
id="s2"
data={symbolDataSource2}
textField="label"
iconImageField="icon"
iconSize={0.5}
textOffset={[0, -1]}
cluster={true}
spiderify={true}
clusterMaxZoom={18}
iconAllowOverlap={true}
textAllowOverlap={true}
/>
<MbSymbolLayer
id="s3"
data={symbolDataSource3}
textField="label"
iconImageField="icon"
iconSize={0.5}
textOffset={[0, -1]}
iconAllowOverlap={true}
textAllowOverlap={true}
/>
<MbBufferPolygonLayer
id="buffer2"
polygon={polygon}
radius={7}
center={mapCenter}
/>
</MbMap>
</div>
);
}
ReactDOM.render(<App />,
document.getElementById("root"))
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 onCreated
event of MbMap
.
- If your component can be placed inside the
MbMap
component, you can use theMapContext
context provided by the component library to get the map instance.
demo3.tsx
import { MbMap } from '@mapbox-react/core'
import Instance1 from './instance1'
function Demo3() {
return (
<div style={{ height: '400px' }} className="vw-full vh-full">
<MbMap>
<Instance1 />
</MbMap>
</div>
)
}
export default Demo3
instance1.tsx
import { useContext } from 'react'
import { MapContext } from '@mapbox-react/core'
function Instance1() {
const mapContext = useContext(MapContext)
console.log(mapContext.mapInstance, mapContext.mapboxInstance)
}
export default Instance1
- 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
onCreated
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-react/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 }
import { MbMap } from '@mapbox-react/core'
import { useMap } from './use-map'
function App() {
const { onCreated } = useMap()
return <MbMap onCreated={onCreated}> ... </MbMap>
}
export default App
In the place where you need to use it:
import { useMap } from './use-map'
const { getMapbox } = useMap()
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-react/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.tsx
import { useEffect } from 'react'
import { useMap } from './use-map'
import { waitingForMap } from './map-deferred'
function Instance() {
const { getMapbox } = useMap()
useEffect(() => {
const operateMap = async() => {
await waitingForMap()
// 下面可以使用getMapbox()获取地图实例进行操作了
console.log('operate', getMapbox())
}
operateMap()
}, [])
return <></>
}
export default Instance
import { MbMap } from '@mapbox-react/core'
import { useMap } from './use-map'
import Instance from './instance'
function App() {
const { onCreated } = useMap()
return <>
<MbMap onCreated={onCreated}> ... </MbMap>
<Instance />
</>
}
export default App
API
PROPS
Name | Description | Type | Default |
---|---|---|---|
antialias | Whether to enable antialiasing; disabling it can improve performance | boolean | true |
bearing | 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 | The geographic center point of the map, using the order of longitude, latitude | number[] | [116.38745, 39.91266] |
mapStyle | 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 | - |
maxBounds | 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 | The initial pitch of the map | number | 0 |
zoom | 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 | - |
extendProps | Extended properties. See the Mapbox documentation | IndexAny | {} |
children | children nodes | any | - |
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: bearing
, center
,pitch
,zoom
, 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
名称 | 描述 | 参数 |
---|---|---|
onCreated | Event triggered when the map is initialized | map: MapboxInstance |
onZoomChange | Event triggered when the map's zoom level changes | number |
onCenterChange | Event triggered when the map's center changes | number[] |
onBearingChange | Event triggered when the map's bearing changes | number |
onPitchChange | Event triggered when the map's pitch changes | number |
onClick | Mouse click event. Triggered on every click | object — Contains screen coordinates pixel , latitude/longitude coordinate , and originalEvent |
onDoubleClick | Mouse double-click event | object — Contains screen coordinates pixel , latitude/longitude coordinate , and originalEvent |
onSingleClick | Mouse single-click event | object — Contains screen coordinates pixel , latitude/longitude coordinate , and originalEvent |
onMouseMove | Mouse move event | object — Contains screen coordinates pixel , latitude/longitude coordinate , and originalEvent |
onMouseOut | Mouse leaves the map area | MapMouseEvent & EventData |
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[] |