【问题标题】:Control zoom level when using geolocate.trigger() in mapbox gl js在 mapbox gl js 中使用 geolocate.trigger() 时控制缩放级别
【发布时间】:2020-08-04 02:36:16
【问题描述】:

我在 react 应用程序中使用 mapbox-gl 来呈现交互式地图。在地图加载时,我想将地图以用户位置为中心,同时保持当前的缩放级别。 geolocate.trigger(); 以用户位置为中心可以正常工作,但地图会自动缩小到大陆级别。这是应用程序地图组件的简化版本。我首先在纽约设置一个硬编码的中心点,它工作正常,然后当 trigger() 运行时,它会被缩小。我试过摆弄 geolocate 对象的所有属性,但它们都对 trigger() 的缩放没有任何影响,而且 trigger 似乎没有任何参数。请注意,出于安全原因,我必须删除我的 mapboxgl.accessToken。 作为旁注,我也试图摆脱较大的蓝色位置置信圈,但尽管设置了 showAccuracyCircle: false,我似乎也无法做到这一点。有什么 mapbox 提示吗?

反应组件:

import React from 'react';
import mapboxgl from 'mapbox-gl';
import './map.css';

mapboxgl.accessToken = 'ACCESS_TOKEN_STRING_GOES_HERE';

export class Map extends React.Component {
  constructor(props) {
  super(props);
    this.state = {
      lng: -73.9392,
      lat: 40.8053,
      zoom: 17.5
    };
  }

  componentDidMount() {
    const map = new mapboxgl.Map({
      container: this.mapContainer,
      style: 'mapbox://styles/mapbox/streets-v11',
      center: [this.state.lng, this.state.lat],
      zoom: this.state.zoom
    });

    const geolocate = new mapboxgl.GeolocateControl({
      container: this.geolocateContainer,
      positionOptions: {enableHighAccuracy: true},
      fitBoundsOptions: {linear: true, maxZoom: 10},
      trackUserLocation: true,
      mapboxgl: mapboxgl,
      showAccuracyCircle: false
      })

    map.on('load', () => {
      geolocate.trigger();
    });

    map.addControl(geolocate);

  }

  render() {
    return (
      <div>
        <div ref={element => this.geolocateContainer = element} className='mapButtons' />
        <div ref={el => this.mapContainer = el} className='mapContainer' />
      </div>
    )
  }
}

这是我放在一起的代码笔,它说明了如果您插入自己的 mapboxgl.accessToken 会出现的问题。如果您仔细观察,当页面加载时,默认视图会以 this.state 中提供的坐标和缩放级别显示。但随后它立即以用户的位置为中心(这是所需的行为)并缩小(我不想缩小)。您需要授予 codepen 页面访问您的位置的权限才能查看此内容。

https://codepen.io/lexandermorgan/pen/ZEWEzze

【问题讨论】:

  • 你真的不需要太强调隐藏你的访问令牌。您可以为此目的创建一个新的公共文件,甚至将其锁定到 codepen。在绝对最坏的情况下,有人会使用您一个月的免费使用量。不过,这从未发生在我身上。

标签: javascript mapbox-gl-js


【解决方案1】:

冒着指出显而易见的风险,您应该设置minZoom,而不是maxZoom

fitBoundsOptions: {linear: true, minZoom: map.getZoom()},

另外,如果您实际上并没有使用地理定位跟踪功能,或者需要控件本身,直接使用浏览器的地理定位 API 可能会更简单:

if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(e => 
    map.jumpTo({ center: [e.coords.longitude, e.coords.latitude]}))
}

【讨论】:

  • 这很有帮助,因为 navigator.geolocation 有效并且是个好主意。但是在 mapboxgl.GeolocateControl 实例的 fitBoundsOptions 中设置 minZoom 没有影响。即使在开始时使用 navigator.geolocation,当按下 geolocate 按钮时,仍然可以使用位置点捕捉到用户的位置,但这仍然会缩小到大陆级别。
  • 也许将代码放在codepen上以帮助调试。您可能可以采取一些棘手的解决方法,例如侦听该特定事件并强制缩放。我想我以前自己也实现过类似的东西。
  • 好点,我在问题中添加了代码笔链接。
【解决方案2】:

我发现了一个稍微不同的解决方法。它使用 ReactMapGL 而不是 MapboxGL。似乎有所不同的事情是将缩放参数传递给临时 geocoderDefaultOverrides 对象,然后解压缩视口,然后将该对象解压缩到 handleGeocoderViewportChange 中的返回对象中。以下是相关部分:

  handleGeocoderViewportChange = viewport => {
    const geocoderDefaultOverrides = { transitionDuration: 0, zoom: 16 };

    return this.handleViewportChange({
      ...viewport,
      ...geocoderDefaultOverrides
    });
  };

然后在渲染中:

  <Geocoder
    mapRef={this.map_ref}
    mapboxApiAccessToken={MBAccessToken}
    onViewportChange={this.handleGeocoderViewportChange}
    viewport={this.state.viewport}
  />

【讨论】:

    猜你喜欢
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 2019-10-28
    • 1970-01-01
    • 2023-01-20
    • 2017-03-14
    • 2017-08-10
    相关资源
    最近更新 更多