Maplibre GL JS 中文文档Maplibre GL JS 中文文档
介绍
插件
样式规范
API
案例
指南
介绍
插件
样式规范
API
案例
指南
  • 介绍
  • 插件
  • 样式规范
    • 弃用功能
    • 表达式
    • 字形
    • 图层
    • 光照
    • 投影
    • 根属性
    • 天空
    • 数据源
    • 精灵图
    • 状态
    • 地形
    • 过渡
    • 类型
  • API
    • media

      • 为 MapLibre GL JS 做贡献
    • Classes

      • AJAXError
      • Actor
      • AlphaImage
      • AttributionControl
      • BoxZoomHandler
      • CanonicalTileID
      • CanvasSource
      • CircleStyleLayer
      • ClickZoomHandler
      • CooperativeGesturesHandler
      • DEMData
      • Dispatcher
      • DoubleClickZoomHandler
      • DragPanHandler
      • DragRotateHandler
      • EdgeInsets
      • ErrorEvent
      • Event
      • Evented
      • FeatureIndex
      • FullscreenControl
      • GeoJSONFeature
      • GeoJSONSource
      • GlobeControl
      • Hash
      • HeatmapStyleLayer
      • ImageAtlas
      • ImageManager
      • ImageSource
      • KeyboardHandler
      • Layout<Props>
      • LngLat
      • LngLatBounds
      • LogoControl
      • Map
      • MapMouseEvent
      • MapTouchEvent
      • MapWheelEvent
      • Marker
      • MercatorCoordinate
      • NavigationControl
      • OverscaledTileID
      • Popup
      • RGBAImage
      • RasterDEMTileSource
      • RasterTileSource
      • ScaleControl
      • ScrollZoomHandler
      • Style
      • abstract StyleLayer
      • SubdivisionGranularityExpression
      • SubdivisionGranularitySetting
      • TapDragZoomHandler
      • TapZoomHandler
      • TerrainControl
      • ThrottledInvoker
      • Tile
      • TouchPanHandler
      • 抽象 TwoFingersTouchHandler
      • TwoFingersTouchPitchHandler
      • TwoFingersTouchRotateHandler
      • TwoFingersTouchZoomHandler
      • TwoFingersTouchZoomRotateHandler
      • VectorTileSource
      • VideoSource
      • WorkerPool
    • Enumerations

      • MessageType
      • ResourceType
      • TextFit
    • Functions

      • addProtocol()
      • addSourceType()
      • clearPrewarmedResources()
      • createTileMesh()
      • getMaxParallelImageRequests()
      • getRTLTextPluginStatus()
      • getVersion()
      • getWorkerCount()
      • getWorkerUrl()
      • importScriptInWorkers()
      • prewarm()
      • removeProtocol()
      • setMaxParallelImageRequests()
      • setWorkerCount()
      • setWorkerUrl()
    • Interfaces

      • ActorTarget
      • AttributeBinder
      • Bucket
      • CustomLayerInterface
      • Handler
      • IActor
      • IControl
      • MousePanHandler
      • MousePitchHandler
      • MouseRollHandler
      • MouseRotateHandler
      • Projection
      • Source
      • StyleImageInterface
      • Subscription
    • Type aliases

      • ActorMessage<T>
      • AddLayerObject
      • AddProtocolAction
      • Alignment
      • AnimationOptions
      • AroundCenterOptions
      • AttributionControlOptions
      • CalculateTileZoomFunction
      • CameraForBoundsOptions
      • CameraOptions
      • CameraUpdateTransformFunction()
      • CanvasSourceSpecification
      • CenterZoomBearing
      • CircleGranularity
      • ClusterIDAndSource
      • Complete<T>
      • Config
      • ControlPosition
      • Coordinates
      • CreateTileMeshOptions
      • CrossFaded<T>
      • CustomRenderMethod()
      • CustomRenderMethodInput
      • DEMEncoding
      • DashEntry
      • DistributiveKeys<T>
      • DistributiveOmit<T, K>
      • DragPanOptions
      • DragRotateHandlerOptions
      • EaseToOptions
      • ExpiryData
      • FeatureIdentifier
      • FitBoundsOptions
      • FlyToOptions
      • FullscreenControlOptions
      • GeoJSONFeatureDiff
      • GeoJSONFeatureId
      • GeoJSONSourceDiff
      • GeoJSONSourceOptions
      • GeoJSONWorkerOptions
      • GeoJSONWorkerSourceLoadDataResult
      • GeolocateControlOptions
      • GestureOptions
      • GetClusterLeavesParams
      • GetGlyphsParameters
      • GetGlyphsResponse
      • GetImagesParameters
      • GetImagesResponse
      • GetResourceResponse<T>
      • GlyphPosition
      • GlyphMetrics
      • GridKey
      • HandlerResult
      • IndicesType
      • JumpToOptions
      • Listener()
      • LngLatBoundsLike
      • LngLatLike
      • LoadGeoJSONParameters
      • LogoControlOptions
      • MapContextEvent
      • MapDataEvent
      • MapEventType
      • MapGeoJSONFeature
      • MapLayerEventType
      • MapLayerMouseEvent
      • MapLayerTouchEvent
      • MapLibreEvent
      • MapLibreZoomEvent
      • MapOptions
      • MapProjectionEvent
      • MapSourceDataType
      • MapSourceDataEvent
      • MapStyleDataEvent
      • MapStyleImageMissingEvent
      • MapTerrainEvent
      • MarkerOptions
      • MessageData
      • NavigationControlOptions
      • /api/type-aliases/Offset.html
      • OverlapMode
      • PaddingOptions
      • PluginState
      • PointLike
      • PointProjection
      • PopupOptions
      • PositionAnchor
      • PossiblyEvaluatedValue<T>
      • ProjectionData
      • ProjectionDataParams
      • QueryRenderedFeaturesOptions
      • QuerySourceFeatureOptions
      • RTLPluginStatus
      • Rect
      • RemoveSourceParams
      • RequestParameters
      • RequestResponseMessageMap
      • RequestTransformFunction()
      • RequireAtLeastOne<T>
      • ScaleControlOptions
      • Serialized
      • SerializedObject<S>
      • SerializedStructArray
      • SetClusterOptions
      • SourceClass()
      • SpriteOnDemandStyleImage
      • StyleGlyph
      • StyleImage
      • StyleImageData
      • StyleImageMetadata
      • StyleOptions
      • StyleSetterOptions
      • StyleSwapOptions
      • SymbolQuad
      • TileMesh
      • TileParameters
      • TileState
      • TransformStyleFunction()
      • Unit
      • UpdateImageOptions
      • UpdateLayersParamaeters
      • WorkerDEMTileParameters
      • WorkerTileParameters
      • WorkerTileResult
  • 案例
    • 3D建筑显示
    • 3D室内地图多边形挤出
    • 3D地形
    • 使用babylon.js添加3D模型
    • 使用three.js添加带阴影的3D模型
    • 在地形上使用three.js添加3D模型
    • 使用three.js添加3D模型
    • 添加默认标记
    • 添加云优化地理TIFF (COG)
    • 使用REST API添加DeckGL图层
    • 添加动画图像
    • 添加生成的图像
    • 动态生成并添加缺失图标到地图
    • 向地图添加可拉伸图片
    • 向地图添加图标
    • 动画线条
    • 绕点相机动画
    • 图像序列动画
    • 标记动画
    • 点动画
    • 沿路径点动画
    • 符号跟随鼠标动画
    • 更改版权信息位置
    • 自定义相机动画
    • 添加Canvas数据源
    • 使地图在点击符号时居中
    • 设置地面以上的中心点
    • 根据缩放级别更改建筑物颜色
    • 更改标签大小写
    • 检查是否支持WebGL
    • 使用自定义属性显示HTML集群
    • 创建和样式化集群
    • 使用按钮更改图层颜色
    • 添加等高线
    • 合作手势
    • 使用自定义标记图标
    • 添加自定义样式图层
    • 使用数据驱动属性设置线条样式
    • 禁用地图旋转
    • 禁用滚动缩放
    • 显示和样式丰富文本标签
    • 创建可拖动标记
    • 创建可拖动点
    • 绘制一个圆形
    • 使用备用图像
    • 使用addProtocol转换特性属性
    • 向多边形添加图案
    • 通过文本输入过滤符号
    • 通过切换列表过滤符号
    • 在图层内过滤
    • 将地图适配到边界框
    • 缓慢飞行到位置
    • 飞行到位置
    • 查看全屏地图
    • 使用游戏控制导航地图
    • 在标签下方添加新图层
    • 添加GeoJSON线条
    • 添加自定义标记
    • 添加GeoJSON多边形
    • 在地球仪上加载3D模型
    • 地球仪大气层
    • 简单自定义地球仪
    • 自定义瓦片地球仪
    • 在地球仪上显示填充挤出层
    • 使用矢量地图显示地球仪
    • 地球仪上缩放和行星大小的关系
    • 哈希路由
    • 地球仪上带地形高程的热力图
    • 创建热力图图层
    • 添加多方向山体阴影图层
    • 添加山体阴影图层
    • 创建悬停效果
    • 显示带地形高程的混合卫星地图
    • 显示非交互式地图
    • 跳转到一系列位置
    • 切换地图语言
    • 显示跨越180度子午线的线条
    • 使用表达式创建渐变线条
    • 添加实时数据
    • 实时更新地图要素
    • 查看本地GeoJSON文件(实验性)
    • 查看本地GeoJSON文件
    • 使用本地生成的表意文字
    • 定位用户位置
    • 细节层次控制
    • 添加栅格瓦片源
    • 使用Mapbox GL Draw绘制多边形
    • 支持从右到左文本
    • 使用 Terra-Draw 绘制几何图形
    • 测量距离
    • 获取鼠标指针坐标
    • 从单个GeoJSON源添加多个几何图形
    • 显示地图导航控件
    • 使用内边距偏移消失点
    • PMTiles 源和协议
    • 点击多边形显示信息
    • 点击显示弹出窗口
    • 悬停显示弹出窗口
    • 显示弹出窗口
    • 获取鼠标指针下的要素
    • 渲染世界副本
    • 限制地图平移到某个区域
    • 显示卫星地图
    • 基于滚动位置飞行到特定位置
    • 设置俯仰角和方位角
    • 为标记添加弹出窗口
    • 显示一个地图
    • 天空、雾和地形
    • 同步多个地图的移动
    • 创建时间轴滑块
    • 切换deck.gl图层
    • 切换交互功能
    • 可变标签放置
    • 可变偏移标签放置
    • 添加矢量瓦片源
    • 在地图上播放视频
    • 可视化人口密度
    • 添加WMS服务
    • 缩放至线要素
  • 指南
    • 优化MapLibre性能: 大型GeoJSON数据集的技巧
    • Leaflet迁移指南
    • Mapbox迁移指南
    • OpenLayers迁移指南

Leaflet迁移指南

本指南旨在帮助您从Leaflet迁移到MapLibre GL JS;虽然这两个库都是用于创建交互式地图的开源JavaScript库,但它们的架构和功能有显著差异;

Leaflet和MapLibre GL JS之间的主要区别

Leaflet是一个专注于二维地图的轻量级库,主要使用栅格瓦片。而MapLibre GL JS是一个更现代的库,提供了二维和三维地图支持,主要使用矢量瓦片,并利用WebGL进行高性能渲染;

关键差异

特性LeafletMapLibre GL JS
瓦片类型主要是栅格瓦片主要是矢量瓦片
渲染主要是DOM和Canvas主要是WebGL
3D支持有限/通过插件原生支持
性能对于简单用例很好对于复杂可视化和大数据集更好
样式CSS和图像JSON样式规范
移动响应性良好优秀
社区庞大、成熟不断增长

地图初始化

Leaflet

// 初始化Leaflet地图
const map = L.map('map').setView([51.505, -0.09], 13);

// 添加瓦片图层
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

MapLibre GL JS

// 初始化MapLibre地图
const map = new maplibregl.Map({
  container: 'map',
  style: 'https://demotiles.maplibre.org/style.json',
  center: [-0.09, 51.505],
  zoom: 13
});

注意坐标顺序的不同:Leaflet使用[纬度, 经度],而MapLibre使用[经度, 纬度];

添加标记

Leaflet

// 添加一个标记
const marker = L.marker([51.5, -0.09]).addTo(map);

// 添加一个带有弹出窗口的标记
marker.bindPopup("<b>你好!</b><br>我是一个弹出窗口。").openPopup();

MapLibre GL JS

// 添加一个标记
const marker = new maplibregl.Marker()
  .setLngLat([-0.09, 51.5])
  .addTo(map);

// 添加一个带有弹出窗口的标记
const popup = new maplibregl.Popup({ offset: 25 })
  .setHTML("<b>你好!</b><br>我是一个弹出窗口。");

marker.setPopup(popup);

处理事件

Leaflet

// 添加点击事件到地图
map.on('click', function(e) {
  console.log("点击坐标: " + e.latlng.toString());
});

// 添加事件到标记
marker.on('click', function(e) {
  console.log("标记被点击了!");
});

MapLibre GL JS

// 添加点击事件到地图
map.on('click', function(e) {
  console.log("点击坐标: " + e.lngLat.toString());
});

// 添加事件到标记
marker.getElement().addEventListener('click', function() {
  console.log("标记被点击了!");
});

添加GeoJSON

Leaflet

// 添加GeoJSON数据
const geojson = {
  "type": "Feature",
  "properties": {},
  "geometry": {
    "type": "Point",
    "coordinates": [-0.09, 51.5]
  }
};

L.geoJSON(geojson).addTo(map);

MapLibre GL JS

// 等待地图加载完成
map.on('load', function() {
  // 添加GeoJSON数据作为源
  map.addSource('point', {
    'type': 'geojson',
    'data': {
      'type': 'Feature',
      'properties': {},
      'geometry': {
        'type': 'Point',
        'coordinates': [-0.09, 51.5]
      }
    }
  });

  // 添加图层来可视化数据
  map.addLayer({
    'id': 'point',
    'type': 'circle',
    'source': 'point',
    'paint': {
      'circle-radius': 10,
      'circle-color': '#3887be'
    }
  });
});

样式

在Leaflet中,样式通常通过CSS和JavaScript选项设置:

// Leaflet样式示例
const circle = L.circle([51.508, -0.11], {
  color: 'red',
  fillColor: '#f03',
  fillOpacity: 0.5,
  radius: 500
}).addTo(map);

在MapLibre GL JS中,样式是通过JSON样式规范和图层属性设置的:

// MapLibre样式示例
map.addLayer({
  'id': 'circle',
  'type': 'circle',
  'source': 'circle-source',
  'paint': {
    'circle-radius': 500,
    'circle-color': '#f03',
    'circle-opacity': 0.5,
    'circle-stroke-color': 'red',
    'circle-stroke-width': 1
  }
});

控件

Leaflet

// 添加缩放控件
L.control.zoom({
  position: 'topright'
}).addTo(map);

// 添加比例尺
L.control.scale().addTo(map);

MapLibre GL JS

// 添加导航控件(包含缩放控件)
map.addControl(new maplibregl.NavigationControl(), 'top-right');

// 添加比例尺
map.addControl(new maplibregl.ScaleControl());

自定义控件

Leaflet

// 创建自定义控件
const customControl = L.Control.extend({
  options: {
    position: 'topright'
  },

  onAdd: function(map) {
    const container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom');
    container.style.backgroundColor = 'white';
    container.style.width = '30px';
    container.style.height = '30px';
    container.innerHTML = '<button>C</button>';
    
    container.onclick = function() {
      console.log('自定义控件被点击了!');
    }
    
    return container;
  }
});

// 添加到地图
map.addControl(new customControl());

MapLibre GL JS

// 创建自定义控件
class CustomControl {
  onAdd(map) {
    this._map = map;
    this._container = document.createElement('div');
    this._container.className = 'maplibregl-ctrl maplibregl-ctrl-group';
    this._container.innerHTML = '<button><span>C</span></button>';
    
    this._container.onclick = function() {
      console.log('自定义控件被点击了!');
    };
    
    return this._container;
  }
  
  onRemove() {
    this._container.parentNode.removeChild(this._container);
    this._map = undefined;
  }
}

// 添加到地图
map.addControl(new CustomControl(), 'top-right');

图层控制

Leaflet

// 创建基础图层
const osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
});

const satellite = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
  attribution: 'Tiles &copy; Esri'
});

// 创建图层控制器
const baseMaps = {
  "标准地图": osm,
  "卫星影像": satellite
};

L.control.layers(baseMaps).addTo(map);

MapLibre GL JS

MapLibre GL JS没有内置的图层切换控件,但我们可以创建一个简单的自定义控件:

// 创建自定义图层切换控件
const layerSwitcher = document.createElement('div');
layerSwitcher.className = 'maplibregl-ctrl maplibregl-ctrl-group';
layerSwitcher.innerHTML = `
  <select id="layer-switcher" style="margin: 5px;">
    <option value="standard">标准地图</option>
    <option value="satellite">卫星影像</option>
  </select>
`;

// 切换样式
document.getElementById('layer-switcher').onchange = function(e) {
  const style = e.target.value;
  if (style === 'standard') {
    map.setStyle('https://demotiles.maplibre.org/style.json');
  } else if (style === 'satellite') {
    map.setStyle('https://api.maptiler.com/maps/hybrid/style.json?key=YOUR_KEY');
  }
};

// 添加到地图(作为自定义控件)
document.querySelector('.maplibregl-ctrl-top-right').appendChild(layerSwitcher);

结语

这个指南涵盖了从Leaflet迁移到MapLibre GL JS的基础知识,但两个库之间还有许多其他差异。MapLibre GL JS提供了更强大的功能,如3D地图、高性能渲染和更多的自定义选项,但也有更陡峭的学习曲线;

在迁移过程中,建议查阅MapLibre GL JS文档以获取更详细的信息和示例;

Prev
优化MapLibre性能: 大型GeoJSON数据集的技巧
Next
Mapbox迁移指南