mapbox-maplibre-migration
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMapLibre to Mapbox Migration Skill
MapLibre到Mapbox迁移技能指南
Expert guidance for migrating from MapLibre GL JS to Mapbox GL JS. Covers the shared history, API compatibility, migration steps, and the advantages of Mapbox's platform.
从MapLibre GL JS迁移到Mapbox GL JS的专业指导,涵盖两者的共享历史、API兼容性、迁移步骤以及Mapbox平台的优势。
Understanding the Fork
了解衍生背景
History
历史
MapLibre GL JS is an open-source fork of Mapbox GL JS v1.13.0, created in December 2020 when Mapbox changed their license starting with v2.0.
Timeline:
- Pre-2020: Mapbox GL JS was open source (BSD license)
- Dec 2020: Mapbox GL JS v2.0 introduced proprietary license
- Dec 2020: Community forked v1.13 as MapLibre GL JS
- Present: Both libraries continue active development
Key Insight: The APIs are ~95% identical because MapLibre started as a Mapbox fork. Most code works in both with minimal changes, making migration straightforward.
MapLibre GL JS 是Mapbox GL JS v1.13.0的开源衍生项目,诞生于2020年12月,当时Mapbox从v2.0版本开始变更了许可证协议。
时间线:
- 2020年前:Mapbox GL JS采用开源(BSD许可证)
- 2020年12月:Mapbox GL JS v2.0引入专有许可证
- 2020年12月:社区基于v1.13版本分叉出MapLibre GL JS
- 当前:两个库均持续活跃开发
核心要点: 由于MapLibre最初是Mapbox的衍生项目,两者API的相似度约为95%。大多数代码只需少量修改即可在两个库中运行,迁移过程非常简单。
Why Migrate to Mapbox?
为何迁移到Mapbox?
Compelling reasons to choose Mapbox GL JS:
- Official Support & SLAs: Enterprise-grade support with guaranteed response times
- Superior Tile Quality: Best-in-class vector tiles with global coverage and frequent updates
- Better Satellite Imagery: High-resolution, up-to-date satellite and aerial imagery
- Rich Ecosystem: Seamless integration with Mapbox Studio, APIs, and services
- Advanced Features: Traffic-aware routing, turn-by-turn directions, premium datasets
- Geocoding & Search: World-class address search and place lookup
- Navigation SDK: Mobile navigation with real-time traffic
- No Tile Infrastructure: No need to host or maintain your own tile servers
- Regular Updates: Continuous improvements and new features
- Professional Services: Access to Mapbox solutions team for complex projects
Mapbox offers a generous free tier: 50,000 map loads/month, making it suitable for many applications without cost.
选择Mapbox GL JS的充分理由:
- 官方支持与服务水平协议(SLAs):企业级支持,提供响应时间保障
- 更优的瓦片质量:业界领先的矢量瓦片,覆盖全球且更新频繁
- 高质量卫星影像:高分辨率、实时更新的卫星与航空影像
- 丰富的生态系统:与Mapbox Studio、各类API及服务无缝集成
- 高级功能:交通感知路由、逐向导航、优质数据集
- 地理编码与搜索:世界级的地址搜索与地点查询能力
- 导航SDK:支持实时交通的移动端导航
- 无需瓦片基础设施:无需自行托管或维护瓦片服务器
- 定期更新:持续改进与新增功能
- 专业服务:针对复杂项目可获取Mapbox解决方案团队的支持
Mapbox提供慷慨的免费额度: 每月50,000次地图加载量,适合许多应用免费使用。
Quick Comparison
快速对比
| Aspect | Mapbox GL JS | MapLibre GL JS |
|---|---|---|
| License | Proprietary (v2+) | BSD 3-Clause (Open Source) |
| Support | Official commercial support | Community support |
| Tiles | Premium Mapbox vector tiles | OSM or custom tile sources |
| Satellite | High-quality global imagery | Requires custom source |
| Token | Required (access token) | Optional (depends on tile source) |
| APIs | Full Mapbox ecosystem | Requires third-party services |
| Studio | Full integration | No native integration |
| 3D Terrain | Built-in with premium data | Available (requires data source) |
| Globe View | v2.9+ | v3.0+ |
| API Compatibility | ~95% compatible with MapLibre | ~95% compatible with Mapbox |
| Bundle Size | ~500KB | ~450KB |
| Setup Complexity | Easy (just add token) | Requires tile source setup |
| 维度 | Mapbox GL JS | MapLibre GL JS |
|---|---|---|
| 许可证 | 专有协议(v2+) | BSD 3-Clause(开源) |
| 支持 | 官方商业支持 | 社区支持 |
| 瓦片 | 优质Mapbox矢量瓦片 | OSM或自定义瓦片源 |
| 卫星影像 | 高质量全球影像 | 需要自定义源 |
| 令牌 | 必填(访问令牌) | 可选(取决于瓦片源) |
| API生态 | 完整的Mapbox生态系统 | 需要第三方服务 |
| Studio集成 | 完全集成 | 无原生集成 |
| 3D地形 | 内置优质数据 | 可用(需数据源支持) |
| 地球视图 | v2.9+ | v3.0+ |
| API兼容性 | 与MapLibre约95%兼容 | 与Mapbox约95%兼容 |
| 包体积 | ~500KB | ~450KB |
| 设置复杂度 | 简单(仅需添加令牌) | 需要配置瓦片源 |
Step-by-Step Migration
分步迁移指南
1. Create Mapbox Account
1. 创建Mapbox账户
- Sign up at mapbox.com
- Get your access token from the account dashboard
- Review pricing: Free tier includes 50,000 map loads/month
- Note your token (starts with for public tokens)
pk.
- 在mapbox.com注册账号
- 从账户控制台获取访问令牌
- 查看定价:免费额度包含每月50,000次地图加载
- 记录你的令牌(公网令牌以开头)
pk.
2. Update Package
2. 更新依赖包
bash
undefinedbash
undefinedRemove MapLibre
移除MapLibre
npm uninstall maplibre-gl
npm uninstall maplibre-gl
Install Mapbox
安装Mapbox
npm install mapbox-gl
undefinednpm install mapbox-gl
undefined3. Update Imports
3. 更新导入语句
javascript
// Before (MapLibre)
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
// After (Mapbox)
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';Or with CDN:
html
<!-- Before (MapLibre) -->
<script src='https://unpkg.com/maplibre-gl@3.0.0/dist/maplibre-gl.js'></script>
<link href='https://unpkg.com/maplibre-gl@3.0.0/dist/maplibre-gl.css' rel='stylesheet' />
<!-- After (Mapbox) -->
<script src='https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.css' rel='stylesheet' />javascript
// 迁移前(MapLibre)
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
// 迁移后(Mapbox)
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';或使用CDN:
html
<!-- 迁移前(MapLibre) -->
<script src='https://unpkg.com/maplibre-gl@3.0.0/dist/maplibre-gl.js'></script>
<link href='https://unpkg.com/maplibre-gl@3.0.0/dist/maplibre-gl.css' rel='stylesheet' />
<!-- 迁移后(Mapbox) -->
<script src='https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.css' rel='stylesheet' />4. Add Access Token
4. 添加访问令牌
javascript
// Add this before map initialization
mapboxgl.accessToken = 'pk.your_mapbox_access_token';Token best practices:
- Use environment variables: or
process.env.VITE_MAPBOX_TOKENprocess.env.NEXT_PUBLIC_MAPBOX_TOKEN - Add URL restrictions in Mapbox dashboard for security
- Use public tokens () for client-side code
pk.* - Never commit tokens to git (add to and
.env).gitignore - Rotate tokens if compromised
See skill for comprehensive token security guidance.
mapbox-token-securityjavascript
// 在地图初始化前添加
mapboxgl.accessToken = 'pk.your_mapbox_access_token';令牌最佳实践:
- 使用环境变量:或
process.env.VITE_MAPBOX_TOKENprocess.env.NEXT_PUBLIC_MAPBOX_TOKEN - 在Mapbox控制台添加URL限制以提升安全性
- 客户端代码使用公网令牌()
pk.* - 切勿将令牌提交至git(添加到并在
.env中忽略).gitignore - 令牌泄露后及时轮换
如需全面的令牌安全指导,请查看技能文档。
mapbox-token-security5. Update Map Initialization
5. 更新地图初始化代码
javascript
// Before (MapLibre)
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json', // or your custom style
center: [-122.4194, 37.7749],
zoom: 12
});
// After (Mapbox)
mapboxgl.accessToken = 'pk.your_mapbox_access_token';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/standard', // Mapbox style
center: [-122.4194, 37.7749],
zoom: 12
});javascript
// 迁移前(MapLibre)
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json', // 或自定义样式
center: [-122.4194, 37.7749],
zoom: 12
});
// 迁移后(Mapbox)
mapboxgl.accessToken = 'pk.your_mapbox_access_token';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/standard', // Mapbox样式
center: [-122.4194, 37.7749],
zoom: 12
});6. Update Style URL
6. 更新样式URL
Mapbox provides professionally designed, maintained styles:
javascript
// Mapbox built-in styles
style: 'mapbox://styles/mapbox/standard' // Mapbox Standard (default)
style: 'mapbox://styles/mapbox/standard-satellite'. // Mapbox Standard Satellite
style: 'mapbox://styles/mapbox/streets-v12' // Streets v12
style: 'mapbox://styles/mapbox/satellite-v9' // Satellite imagery
style: 'mapbox://styles/mapbox/satellite-streets-v12' // Hybrid
style: 'mapbox://styles/mapbox/outdoors-v12' // Outdoor/recreation
style: 'mapbox://styles/mapbox/light-v11' // Light theme
style: 'mapbox://styles/mapbox/dark-v11' // Dark theme
style: 'mapbox://styles/mapbox/navigation-day-v1' // Navigation (day)
style: 'mapbox://styles/mapbox/navigation-night-v1' // Navigation (night)Custom styles:
You can also create and use custom styles from Mapbox Studio:
javascript
style: 'mapbox://styles/your-username/your-style-id'Mapbox提供专业设计、维护的样式:
javascript
// Mapbox内置样式
style: 'mapbox://styles/mapbox/standard' // Mapbox标准样式(默认)
style: 'mapbox://styles/mapbox/standard-satellite'. // Mapbox标准卫星样式
style: 'mapbox://styles/mapbox/streets-v12' // 街道样式v12
style: 'mapbox://styles/mapbox/satellite-v9' // 卫星影像
style: 'mapbox://styles/mapbox/satellite-streets-v12' // 混合样式
style: 'mapbox://styles/mapbox/outdoors-v12' // 户外/休闲样式
style: 'mapbox://styles/mapbox/light-v11' // 浅色主题
style: 'mapbox://styles/mapbox/dark-v11' // 深色主题
style: 'mapbox://styles/mapbox/navigation-day-v1' // 导航样式(日间)
style: 'mapbox://styles/mapbox/navigation-night-v1' // 导航样式(夜间)自定义样式:
你也可以在Mapbox Studio中创建并使用自定义样式:
javascript
style: 'mapbox://styles/your-username/your-style-id'7. Update All References
7. 更新所有引用
Replace all references with :
maplibreglmapboxgljavascript
// Markers
const marker = new mapboxgl.Marker() // was: maplibregl.Marker()
.setLngLat([-122.4194, 37.7749])
.setPopup(new mapboxgl.Popup().setText('San Francisco'))
.addTo(map);
// Controls
map.addControl(new mapboxgl.NavigationControl(), 'top-right');
map.addControl(new mapboxgl.GeolocateControl());
map.addControl(new mapboxgl.FullscreenControl());
map.addControl(new mapboxgl.ScaleControl());将所有引用替换为:
maplibreglmapboxgljavascript
// 标记
const marker = new mapboxgl.Marker() // 原:maplibregl.Marker()
.setLngLat([-122.4194, 37.7749])
.setPopup(new mapboxgl.Popup().setText('San Francisco'))
.addTo(map);
// 控件
map.addControl(new mapboxgl.NavigationControl(), 'top-right');
map.addControl(new mapboxgl.GeolocateControl());
map.addControl(new mapboxgl.FullscreenControl());
map.addControl(new mapboxgl.ScaleControl());8. Update Plugins (If Used)
8. 更新插件(如已使用)
Some MapLibre plugins should be replaced with Mapbox versions:
| MapLibre Plugin | Mapbox Alternative |
|---|---|
| |
| |
| |
Example:
javascript
// Before (MapLibre)
import MaplibreGeocoder from '@maplibre/maplibre-gl-geocoder';
// After (Mapbox)
import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
map.addControl(new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl
}));部分MapLibre插件需替换为Mapbox版本:
| MapLibre插件 | Mapbox替代方案 |
|---|---|
| |
| |
| |
示例:
javascript
// 迁移前(MapLibre)
import MaplibreGeocoder from '@maplibre/maplibre-gl-geocoder';
// 迁移后(Mapbox)
import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
map.addControl(new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl
}));9. Everything Else Stays the Same
9. 其余代码保持不变
All your map code, events, layers, and sources work identically:
javascript
// This code works EXACTLY THE SAME in both libraries
map.on('load', () => {
map.addSource('points', {
type: 'geojson',
data: geojsonData
});
map.addLayer({
id: 'points-layer',
type: 'circle',
source: 'points',
paint: {
'circle-radius': 8,
'circle-color': '#ff0000'
}
});
});
// Events work identically
map.on('click', 'points-layer', (e) => {
console.log(e.features[0].properties);
});
// All map methods work the same
map.setCenter([lng, lat]);
map.setZoom(12);
map.fitBounds(bounds);
map.flyTo({center: [lng, lat], zoom: 14});所有地图代码、事件、图层和数据源均可直接使用:
javascript
// 这段代码在两个库中的运行效果完全一致
map.on('load', () => {
map.addSource('points', {
type: 'geojson',
data: geojsonData
});
map.addLayer({
id: 'points-layer',
type: 'circle',
source: 'points',
paint: {
'circle-radius': 8,
'circle-color': '#ff0000'
}
});
});
// 事件处理完全一致
map.on('click', 'points-layer', (e) => {
console.log(e.features[0].properties);
});
// 所有地图方法用法相同
map.setCenter([lng, lat]);
map.setZoom(12);
map.fitBounds(bounds);
map.flyTo({center: [lng, lat], zoom: 14});What Changes: Summary
变更内容总结
Must change:
- Package name (→
maplibre-gl)mapbox-gl - Import statements
- Add configuration
mapboxgl.accessToken - Style URL (switch to styles)
mapbox:// - Plugin packages (if used)
Stays exactly the same:
- All map methods (,
setCenter,setZoom,fitBounds, etc.)flyTo - All event handling (,
map.on('click'), etc.)map.on('load') - Marker/Popup APIs (100% compatible)
- Layer/source APIs (100% compatible)
- GeoJSON handling
- Custom styling and expressions
- Controls (Navigation, Geolocate, Scale, etc.)
必须修改的内容:
- 包名称(→
maplibre-gl)mapbox-gl - 导入语句
- 添加配置
mapboxgl.accessToken - 样式URL(切换为格式的样式)
mapbox:// - 插件包(如已使用)
完全无需修改的内容:
- 所有地图方法(、
setCenter、setZoom、fitBounds等)flyTo - 所有事件处理(、
map.on('click')等)map.on('load') - Marker/Popup API(100%兼容)
- 图层/数据源API(100%兼容)
- GeoJSON处理
- 自定义样式与表达式
- 控件(导航、定位、比例尺等)
API Compatibility Matrix
API兼容性矩阵
100% Compatible APIs
100%兼容的API
These work identically in both libraries:
javascript
// Map methods
map.setCenter([lng, lat])
map.setZoom(zoom)
map.fitBounds(bounds)
map.panTo([lng, lat])
map.flyTo({center, zoom})
map.getCenter()
map.getZoom()
map.getBounds()
map.resize()
// Events
map.on('load', callback)
map.on('click', callback)
map.on('move', callback)
map.on('zoom', callback)
map.on('rotate', callback)
// Markers
new mapboxgl.Marker()
marker.setLngLat([lng, lat])
marker.setPopup(popup)
marker.addTo(map)
marker.remove()
marker.setDraggable(true)
// Popups
new mapboxgl.Popup()
popup.setLngLat([lng, lat])
popup.setHTML(html)
popup.setText(text)
popup.addTo(map)
// Sources & Layers
map.addSource(id, source)
map.removeSource(id)
map.addLayer(layer)
map.removeLayer(id)
map.getSource(id)
map.getLayer(id)
// Styling
map.setPaintProperty(layerId, property, value)
map.setLayoutProperty(layerId, property, value)
map.setFilter(layerId, filter)
// Controls
map.addControl(control, position)
new mapboxgl.NavigationControl()
new mapboxgl.GeolocateControl()
new mapboxgl.FullscreenControl()
new mapboxgl.ScaleControl()这些API在两个库中的用法完全一致:
javascript
// 地图方法
map.setCenter([lng, lat])
map.setZoom(zoom)
map.fitBounds(bounds)
map.panTo([lng, lat])
map.flyTo({center, zoom})
map.getCenter()
map.getZoom()
map.getBounds()
map.resize()
// 事件
map.on('load', callback)
map.on('click', callback)
map.on('move', callback)
map.on('zoom', callback)
map.on('rotate', callback)
// 标记
new mapboxgl.Marker()
marker.setLngLat([lng, lat])
marker.setPopup(popup)
marker.addTo(map)
marker.remove()
marker.setDraggable(true)
// 弹窗
new mapboxgl.Popup()
popup.setLngLat([lng, lat])
popup.setHTML(html)
popup.setText(text)
popup.addTo(map)
// 数据源与图层
map.addSource(id, source)
map.removeSource(id)
map.addLayer(layer)
map.removeLayer(id)
map.getSource(id)
map.getLayer(id)
// 样式设置
map.setPaintProperty(layerId, property, value)
map.setLayoutProperty(layerId, property, value)
map.setFilter(layerId, filter)
// 控件
map.addControl(control, position)
new mapboxgl.NavigationControl()
new mapboxgl.GeolocateControl()
new mapboxgl.FullscreenControl()
new mapboxgl.ScaleControl()Side-by-Side Example
对比示例
MapLibre GL JS (Before)
MapLibre GL JS(迁移前)
javascript
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
// No token needed for OSM tiles
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json',
center: [-122.4194, 37.7749],
zoom: 12
});
map.on('load', () => {
new maplibregl.Marker()
.setLngLat([-122.4194, 37.7749])
.setPopup(new maplibregl.Popup().setText('San Francisco'))
.addTo(map);
});javascript
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
// 使用OSM瓦片无需令牌
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json',
center: [-122.4194, 37.7749],
zoom: 12
});
map.on('load', () => {
new maplibregl.Marker()
.setLngLat([-122.4194, 37.7749])
.setPopup(new maplibregl.Popup().setText('San Francisco'))
.addTo(map);
});Mapbox GL JS (After)
Mapbox GL JS(迁移后)
javascript
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
// Add your Mapbox token
mapboxgl.accessToken = 'pk.your_mapbox_access_token';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [-122.4194, 37.7749],
zoom: 12
});
map.on('load', () => {
new mapboxgl.Marker()
.setLngLat([-122.4194, 37.7749])
.setPopup(new mapboxgl.Popup().setText('San Francisco'))
.addTo(map);
});What's different: Package, import, token, and style URL. Everything else is identical.
javascript
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
// 添加你的Mapbox令牌
mapboxgl.accessToken = 'pk.your_mapbox_access_token';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [-122.4194, 37.7749],
zoom: 12
});
map.on('load', () => {
new mapboxgl.Marker()
.setLngLat([-122.4194, 37.7749])
.setPopup(new mapboxgl.Popup().setText('San Francisco'))
.addTo(map);
});差异点: 包依赖、导入语句、令牌配置和样式URL。其余代码完全一致。
Mapbox-Exclusive Features
Mapbox专属功能
After migration, you gain access to these Mapbox-only features:
迁移后,你可以使用以下Mapbox专属功能:
Premium Vector Tiles
优质矢量瓦片
- Streets: Comprehensive road network with names, shields, and routing data
- Satellite: High-resolution global imagery updated regularly
- Terrain: Elevation data with hillshading and 3D terrain
- Traffic: Real-time traffic data (with Navigation SDK)
- 街道瓦片:包含名称、标识和路由数据的全面道路网络
- 卫星瓦片:高分辨率全球影像,定期更新
- 地形瓦片:带晕渲的高程数据与3D地形
- 交通瓦片:实时交通数据(需导航SDK)
Mapbox APIs
Mapbox API
Use these APIs alongside your map for enhanced functionality:
javascript
// Geocoding API - Convert addresses to coordinates
const response = await fetch(
`https://api.mapbox.com/search/geocode/v6/forward?q=San+Francisco&access_token=${mapboxgl.accessToken}`
);
// Directions API - Get turn-by-turn directions
const directions = await fetch(
`https://api.mapbox.com/directions/v5/mapbox/driving/-122.42,37.78;-122.45,37.76?access_token=${mapboxgl.accessToken}`
);
// Isochrone API - Calculate travel time polygons
const isochrone = await fetch(
`https://api.mapbox.com/isochrone/v1/mapbox/driving/-122.42,37.78?contours_minutes=5,10,15&access_token=${mapboxgl.accessToken}`
);可结合地图使用这些API增强功能:
javascript
// 地理编码API - 将地址转换为坐标
const response = await fetch(
`https://api.mapbox.com/search/geocode/v6/forward?q=San+Francisco&access_token=${mapboxgl.accessToken}`
);
// 路径规划API - 获取逐向导航路线
const directions = await fetch(
`https://api.mapbox.com/directions/v5/mapbox/driving/-122.42,37.78;-122.45,37.76?access_token=${mapboxgl.accessToken}`
);
// 等时线API - 计算出行时间多边形
const isochrone = await fetch(
`https://api.mapbox.com/isochrone/v1/mapbox/driving/-122.42,37.78?contours_minutes=5,10,15&access_token=${mapboxgl.accessToken}`
);Mapbox Studio
Mapbox Studio
- Visual style editor with live preview
- Dataset management and editing
- Tilesets with custom data upload
- Collaborative team features
- Style versioning and publishing
- 带实时预览的可视化样式编辑器
- 数据集管理与编辑
- 支持自定义数据上传的瓦片集
- 协作团队功能
- 样式版本控制与发布
Advanced Features (v2.9+)
高级功能(v2.9+)
- Globe projection: Seamless transition from globe to Mercator
- 3D buildings: Extrusion with real building footprints
- Custom terrain: Use your own DEM sources
- Sky layer: Realistic atmospheric rendering
- 地球投影:从地球到墨卡托投影的无缝切换
- 3D建筑:基于真实建筑轮廓的拉伸效果
- 自定义地形:可使用自有DEM数据源
- 天空图层:逼真的大气渲染
Framework Integration
框架集成
Migration works identically across all frameworks. See skill for detailed React, Vue, Svelte, Angular patterns.
mapbox-web-integration-patterns迁移流程在所有框架中完全一致。如需详细的React、Vue、Svelte、Angular集成方案,请查看技能文档。
mapbox-web-integration-patternsReact Example
React示例
jsx
import { useRef, useEffect } from 'react';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
// Set token once (can be in app initialization)
mapboxgl.accessToken = process.env.REACT_APP_MAPBOX_TOKEN;
function MapComponent() {
const mapRef = useRef(null);
const mapContainerRef = useRef(null);
useEffect(() => {
mapRef.current = new mapboxgl.Map({
container: mapContainerRef.current,
style: 'mapbox://styles/mapbox/streets-v12',
center: [-122.4194, 37.7749],
zoom: 12
});
return () => {
mapRef.current.remove();
};
}, []);
return <div ref={mapContainerRef} style={{ height: '100vh' }} />;
}Just replace with and update token/style - everything else is identical!
maplibreglmapboxgljsx
import { useRef, useEffect } from 'react';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
// 全局设置一次令牌(可在应用初始化时配置)
mapboxgl.accessToken = process.env.REACT_APP_MAPBOX_TOKEN;
function MapComponent() {
const mapRef = useRef(null);
const mapContainerRef = useRef(null);
useEffect(() => {
mapRef.current = new mapboxgl.Map({
container: mapContainerRef.current,
style: 'mapbox://styles/mapbox/streets-v12',
center: [-122.4194, 37.7749],
zoom: 12
});
return () => {
mapRef.current.remove();
};
}, []);
return <div ref={mapContainerRef} style={{ height: '100vh' }} />;
}只需将替换为并更新令牌与样式——其余代码完全一致!
maplibreglmapboxglVue Example
Vue示例
vue
<template>
<div ref="mapContainer" class="map-container"></div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
mapboxgl.accessToken = import.meta.env.VITE_MAPBOX_TOKEN;
const mapContainer = ref(null);
let map = null;
onMounted(() => {
map = new mapboxgl.Map({
container: mapContainer.value,
style: 'mapbox://styles/mapbox/streets-v12',
center: [-122.4194, 37.7749],
zoom: 12
});
});
onUnmounted(() => {
map?.remove();
});
</script>
<style scoped>
.map-container {
height: 100vh;
}
</style>vue
<template>
<div ref="mapContainer" class="map-container"></div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
mapboxgl.accessToken = import.meta.env.VITE_MAPBOX_TOKEN;
const mapContainer = ref(null);
let map = null;
onMounted(() => {
map = new mapboxgl.Map({
container: mapContainer.value,
style: 'mapbox://styles/mapbox/streets-v12',
center: [-122.4194, 37.7749],
zoom: 12
});
});
onUnmounted(() => {
map?.remove();
});
</script>
<style scoped>
.map-container {
height: 100vh;
}
</style>Common Migration Issues
常见迁移问题
Issue 1: Token Not Set
问题1:未设置令牌
Problem:
javascript
// Error: "A valid Mapbox access token is required to use Mapbox GL"
const map = new mapboxgl.Map({...});Solution:
javascript
// Set token BEFORE creating map
mapboxgl.accessToken = 'pk.your_token';
const map = new mapboxgl.Map({...});问题现象:
javascript
// 错误提示:"使用Mapbox GL需要有效的访问令牌"
const map = new mapboxgl.Map({...});解决方案:
javascript
// 在创建地图前设置令牌
mapboxgl.accessToken = 'pk.your_token';
const map = new mapboxgl.Map({...});Issue 2: Token in Git
问题2:令牌提交至Git
Problem:
javascript
// Token hardcoded in source
mapboxgl.accessToken = 'pk.eyJ1Ijoi...';Solution:
javascript
// Use environment variables
mapboxgl.accessToken = process.env.VITE_MAPBOX_TOKEN;
// Add to .env file (not committed to git)
VITE_MAPBOX_TOKEN=pk.your_token
// Add .env to .gitignore
echo ".env" >> .gitignore问题现象:
javascript
// 令牌硬编码在源码中
mapboxgl.accessToken = 'pk.eyJ1Ijoi...';解决方案:
javascript
// 使用环境变量
mapboxgl.accessToken = process.env.VITE_MAPBOX_TOKEN;
// 添加到.env文件(不提交至git)
VITE_MAPBOX_TOKEN=pk.your_token
// 将.env添加到.gitignore
echo ".env" >> .gitignoreIssue 3: Wrong Style URL Format
问题3:样式URL格式错误
Problem:
javascript
// MapLibre-style URL won't work optimally
style: 'https://demotiles.maplibre.org/style.json'Solution:
javascript
// Use Mapbox style URL for better performance and features
style: 'mapbox://styles/mapbox/streets-v12'问题现象:
javascript
// MapLibre格式的URL无法发挥最佳性能
style: 'https://demotiles.maplibre.org/style.json'解决方案:
javascript
// 使用Mapbox样式URL以获得更好的性能和功能
style: 'mapbox://styles/mapbox/streets-v12'Issue 4: Plugin Compatibility
问题4:插件兼容性
Problem:
javascript
// MapLibre plugin won't work
import MaplibreGeocoder from '@maplibre/maplibre-gl-geocoder';Solution:
javascript
// Use Mapbox plugin
import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';问题现象:
javascript
// MapLibre插件无法正常工作
import MaplibreGeocoder from '@maplibre/maplibre-gl-geocoder';解决方案:
javascript
// 使用Mapbox官方插件
import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';Issue 5: CDN URLs
问题5:CDN地址错误
Problem:
javascript
// Wrong CDN
<script src='https://unpkg.com/maplibre-gl@3.0.0/dist/maplibre-gl.js'></script>Solution:
javascript
// Use Mapbox CDN
<script src='https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.css' rel='stylesheet' />问题现象:
javascript
// 使用了错误的CDN
<script src='https://unpkg.com/maplibre-gl@3.0.0/dist/maplibre-gl.js'></script>解决方案:
javascript
// 使用Mapbox官方CDN
<script src='https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.css' rel='stylesheet' />Migration Checklist
迁移检查清单
Complete these steps for a successful migration:
- Create Mapbox account and get access token
- Update package: (remove maplibre-gl)
npm install mapbox-gl - Update imports: →
maplibre-glmapbox-gl - Update CSS imports: →
maplibre-gl.cssmapbox-gl.css - Add token: Set
mapboxgl.accessToken = 'pk.xxx' - Use environment variables: Store token in
.env - Update style URL: Change to
mapbox://styles/mapbox/streets-v12 - Update all references: Replace with
maplibregl.mapboxgl. - Update plugins: Install Mapbox versions of plugins (if used)
- Configure token security: Add URL restrictions in dashboard
- Test all functionality: Verify map loads, interactions work
- Set up billing alerts: Monitor usage in Mapbox dashboard
- Update documentation: Document token setup for team
- Add .env to .gitignore: Ensure tokens not committed
完成以下步骤确保迁移成功:
- 创建Mapbox账户并获取访问令牌
- 更新依赖包:(移除maplibre-gl)
npm install mapbox-gl - 更新导入语句:→
maplibre-glmapbox-gl - 更新CSS导入:→
maplibre-gl.cssmapbox-gl.css - 添加令牌:设置
mapboxgl.accessToken = 'pk.xxx' - 使用环境变量:将令牌存储在中
.env - 更新样式URL:改为格式
mapbox://styles/mapbox/streets-v12 - 更新所有引用:将替换为
maplibregl.mapboxgl. - 更新插件:安装Mapbox版本的插件(如已使用)
- 配置令牌安全:在控制台添加URL限制
- 测试所有功能:验证地图加载、交互正常
- 设置账单提醒:在Mapbox控制台监控使用量
- 更新文档:为团队记录令牌设置流程
- 将.env添加到.gitignore:确保令牌不被提交
Why Choose Mapbox
为何选择Mapbox
For Production Applications
面向生产应用
Reliability & Support:
- 99.9% uptime SLA for enterprise customers
- 24/7 support with guaranteed response times
- Dedicated solutions engineers for complex projects
- Regular platform updates and improvements
Performance:
- Global CDN for fast tile delivery
- Optimized vector tiles for minimal bandwidth
- Automatic scaling for traffic spikes
- WebGL-accelerated rendering
Features:
- Professional cartography and design
- Regular map data updates
- Traffic and routing data
- Premium satellite imagery
- 3D terrain and buildings
可靠性与支持:
- 企业客户可享受99.9%的正常运行时间SLA
- 7×24小时支持,提供响应时间保障
- 针对复杂项目的专属解决方案工程师
- 持续的平台更新与改进
性能:
- 全球CDN加速瓦片分发
- 优化的矢量瓦片,减少带宽消耗
- 流量峰值时自动扩容
- WebGL加速渲染
功能:
- 专业的地图制图与设计
- 定期更新的地图数据
- 交通与路由数据
- 优质卫星影像
- 3D地形与建筑
For Development Teams
面向开发团队
Developer Experience:
- Comprehensive documentation with examples
- Active community and forums
- Regular SDK updates
- TypeScript support (via )
@types/mapbox-gl - Extensive example gallery
Ecosystem Integration:
- Seamless Studio integration
- API consistency across services
- Mobile SDKs (iOS, Android, React Native)
- Unity and Unreal Engine plugins
- Analytics and monitoring tools
开发者体验:
- 包含示例的全面文档
- 活跃的社区与论坛
- 定期的SDK更新
- TypeScript支持(通过)
@types/mapbox-gl - 丰富的示例库
生态系统集成:
- 与Studio无缝集成
- 服务间API一致性
- 移动端SDK(iOS、Android、React Native)
- Unity与Unreal Engine插件
- 分析与监控工具
For Business
面向业务
Predictable Costs:
- Clear, usage-based pricing
- Free tier for development and small apps
- No infrastructure costs
- Scalable pricing for growth
Compliance & Security:
- SOC 2 Type II certified
- GDPR compliant
- Enterprise security features
- Audit logs and monitoring
No Infrastructure Burden:
- No tile servers to maintain
- No storage or bandwidth concerns
- No update management
- Focus on your application, not infrastructure
可预测的成本:
- 清晰的基于使用量的定价
- 开发与小型应用可使用免费额度
- 无基础设施成本
- 随业务增长可扩展的定价
合规与安全:
- SOC 2 Type II认证
- GDPR合规
- 企业级安全功能
- 审计日志与监控
无基础设施负担:
- 无需维护瓦片服务器
- 无需担心存储与带宽
- 无需管理更新
- 专注于你的应用,而非基础设施
Performance Comparison
性能对比
Both libraries have similar rendering performance as they share the same core codebase:
| Metric | Mapbox GL JS | MapLibre GL JS |
|---|---|---|
| Bundle size | ~500KB | ~450KB |
| Initial load | Similar | Similar |
| Rendering | WebGL-based | WebGL-based |
| Memory usage | Similar | Similar |
| Tile loading | Faster (CDN + optimized tiles) | Depends on tile source |
Key insight: Choose based on features, support, and tile quality, not rendering performance. Mapbox's advantage is in tile delivery speed, data quality, and ecosystem integration.
由于共享核心代码库,两个库的渲染性能相似:
| 指标 | Mapbox GL JS | MapLibre GL JS |
|---|---|---|
| 包体积 | ~500KB | ~450KB |
| 初始加载速度 | 相似 | 相似 |
| 渲染方式 | 基于WebGL | 基于WebGL |
| 内存占用 | 相似 | 相似 |
| 瓦片加载速度 | 更快(CDN+优化瓦片) | 取决于瓦片源 |
核心结论: 选择时应基于功能、支持与瓦片质量,而非渲染性能。Mapbox的优势在于瓦片分发速度、数据质量与生态系统集成。
Integration with Other Skills
与其他技能的集成
Related skills:
- mapbox-web-integration-patterns: Framework-specific patterns (React, Vue, Svelte, Angular)
- mapbox-web-performance-patterns: Performance optimization techniques
- mapbox-token-security: Comprehensive token security best practices
- mapbox-google-maps-migration: Migrate from Google Maps to Mapbox
相关技能:
- mapbox-web-integration-patterns:框架特定集成方案(React、Vue、Svelte、Angular)
- mapbox-web-performance-patterns:性能优化技巧
- mapbox-token-security:全面的令牌安全最佳实践
- mapbox-google-maps-migration:从Google Maps迁移到Mapbox
Resources
资源
Mapbox GL JS:
- Official Documentation
- Example Gallery
- API Reference
- GitHub Repository
- Mapbox Studio
- Pricing Information
Migration Support:
Quick Reference
快速参考
Key Differences Summary
核心差异总结
| What | MapLibre | Mapbox |
|---|---|---|
| Package | | |
| Import | | |
| Token | Optional (depends on tiles) | Required: |
| Style | Custom URL or OSM tiles | |
| License | BSD (Open Source) | Proprietary (v2+) |
| Support | Community | Official commercial support |
| Tiles | Requires tile source | Premium Mapbox tiles included |
| APIs | Third-party | Full Mapbox API ecosystem |
| API | ~95% compatible | ~95% compatible |
Bottom line: Migration is easy because APIs are nearly identical. Main changes are packaging, token setup, and style URLs. The result is access to Mapbox's premium tiles, ecosystem, and support.
| 内容 | MapLibre | Mapbox |
|---|---|---|
| 包名称 | | |
| 导入语句 | | |
| 令牌 | 可选(取决于瓦片源) | 必填: |
| 样式URL | 自定义URL或OSM瓦片 | |
| 许可证 | BSD(开源) | 专有协议(v2+) |
| 支持方式 | 社区支持 | 官方商业支持 |
| 瓦片源 | 需要自行提供 | 包含优质Mapbox瓦片 |
| API生态 | 第三方服务 | 完整的Mapbox API生态 |
| API兼容性 | 与Mapbox约95%兼容 | 与MapLibre约95%兼容 |
总结: 由于API高度相似,迁移过程非常简单。主要变更为包依赖、令牌配置与样式URL。迁移后可获得Mapbox的优质瓦片、生态系统与官方支持。