在React-Leaflet中呈现Mapbox矢量瓦片?

7
4个回答

6

对于react-leaflet v2,需要将MapBoxGLLayer组件与HOC withLeaflet()一起导出才能使其正常工作。

步骤:

1.安装mapbox-gl-leaflet

npm i mapbox-gl-leaflet 

2. 将 mapbox-gl js 和 css 添加到 index.html

<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.css' rel='stylesheet' />  

3.添加此组件。

import L from "leaflet";
import {} from "mapbox-gl-leaflet";
import PropTypes from "prop-types";
import { GridLayer, withLeaflet } from "react-leaflet";

class MapBoxGLLayer extends GridLayer {
  createLeafletElement(props) {
    return L.mapboxGL(props);
  }
}

/*
* Props are the options supported by Mapbox Map object
* Find options here:https://www.mapbox.com/mapbox-gl-js/api/#new-mapboxgl-map-options-
*/
MapBoxGLLayer.propTypes = {
  accessToken: PropTypes.string.isRequired,
  style: PropTypes.string
};

MapBoxGLLayer.defaultProps = {
  style: "mapbox://styles/mapbox/streets-v9"
};

export default withLeaflet(MapBoxGLLayer);   

4. 使用 MapBoxGLLayer 组件。

class App extends Component {
  state = {
    center: [51.505, -0.091],
    zoom: 13
  };

  render() {
    return (
      <div>
        <Map center={this.state.center} zoom={this.state.zoom}>
          <MapBoxGLLayer
            accessToken={MAPBOX_ACCESS_TOKEN}
            style="mapbox://styles/mapbox/streets-v9"
          />
        </Map>
      </div>
    );
  }
}

在此处找到可运行的代码(添加您自己的Mapbox令牌):https://codesandbox.io/s/ooypokn26y

这对我非常有帮助。唯一的问题是,<MapboxLayer /> 应该改为 <MapBoxGLLayer />。 - jennEDVT
@MurliPrajapati 我正在努力理解以下内容: import L from "leaflet"; import {} from "mapbox-gl-leaflet"; ... return L.mapboxGL(props);因此,'L'是引用leaflet,并且它没有.mapboxGL()函数 - 这是否从mapbox-gl-leaflet中提取?(我正在尝试理解以便将其转换为TypeScript) - BruceM
@BruceM L.mapboxGL() 函数由 mapbox-gl-leaflet 提供。该库将此函数添加到全局变量 L 中。您可以在这里查看:https://github.com/mapbox/mapbox-gl-leaflet/blob/b04674c701bada403ca428d08dce550b5ecd9863/leaflet-mapbox-gl.js#L236 - Murli Prajapati
非常感谢 - 一旦我添加了TypeScript类型文件,它就开始工作了。 - BruceM
嘿!有什么想法可以在@mapbox/mapbox-gl-language中添加语言检测支持吗?只是试图找到获取map.AddControl访问权限的方法。 - Stanislav Glushak

3

在这个react-leaflet issue中有一些非常不错的矢量切片示例(下面是重现的mapbox-gl示例)。

// @flow

import L from 'leaflet'
import {} from 'mapbox-gl-leaflet'
import {PropTypes} from 'react'
import { GridLayer } from 'react-leaflet'

export default class MapBoxGLLayer extends GridLayer {
  static propTypes = {
    opacity: PropTypes.number,
    accessToken: PropTypes.string.isRequired,
    style: PropTypes.string,
    zIndex: PropTypes.number,
  }

  createLeafletElement(props: Object): Object {
    return L.mapboxGL(props)
  }
}

和上述组件的使用:

<Map>
  <MapBoxGLLayer
    url={url}
    accessToken={MAPBOX_ACCESS_TOKEN}
    style='https://style.example.com/style.json'
  />
</Map>

注意: 您可能还需要npm install mapbox-gl并将该库导入并分配给全局变量window.mapboxgl = mapboxgl,以避免出现mapboxgl未定义的问题。


当我尝试访问我的扩展GridLayer时,出现“无法读取未定义的属性'layerContainer'”的错误消息。因此,该消息显示为:在MapLayer.js的第77行,无法读取未定义的属性'layerContainer'。有什么建议吗? - BardZH

2
您可以通过扩展MapLayer组件来创建自定义组件。您可以在我贡献的一个项目这里中看到如何完成react-leaflet 1.0的示例。

0
如果有人发现这个问题并想知道如何使用MapLibre GL JS(Mapbox GL JS的FOSS分支)作为后端渲染器,那么你可以做到,但这并不是显而易见的。 MapLibre等效插件现在正在积极维护,而Mapbox则没有。

这是一个组件代码(TypeScript),用于MapLibre瓷砖图层,您可以在React Leaflet MapContainer中使用它来替代TileLayer

import {
    type LayerProps,
    createElementObject,
    createTileLayerComponent,
    updateGridLayer,
    withPane,
} from '@react-leaflet/core'
import L from 'leaflet'
import '@maplibre/maplibre-gl-leaflet'

export interface MapLibreTileLayerProps extends L.LeafletMaplibreGLOptions, LayerProps {
    url: string,
    attribution: string,
}

export const MapLibreTileLayer = createTileLayerComponent<
    L.MaplibreGL,
    MapLibreTileLayerProps
>(
    function createTileLayer({ url, attribution, ...options }, context) {
        const layer = L.maplibreGL({style: url, attribution: attribution, noWrap: true}, withPane(options, context))
        return createElementObject(layer, context)
    },
    function updateTileLayer(layer, props, prevProps) {
        updateGridLayer(layer, props, prevProps)

        const { url, attribution } = props
        if (url != null && url !== prevProps.url) {
            layer.getMaplibreMap().setStyle(url)
        }

        if (attribution != null && attribution !== prevProps.attribution) {
            layer.options.attribution = attribution
        }
    },
)

完整的示例代码存放在 GitHub 上的此仓库中:https://github.com/stadiamaps/react-leaflet-demo


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接