Управление уровнем масштабирования при использовании geolocate.trigger () в mapbox gl js - PullRequest
1 голос
/ 04 августа 2020

Я использую mapbox-gl в приложении реакции для визуализации интерактивной карты. При загрузке карты я хочу центрировать карту относительно местоположения пользователя, сохраняя текущий уровень масштабирования. Центрирование местоположения пользователя отлично работает с geolocate.trigger();, но карта автоматически масштабируется до уровня континента. Вот упрощенная версия компонента карты приложения. Я начинаю с установки жестко запрограммированной центральной точки в Нью-Йорке, которая отлично работает, а затем, когда запускается метод trigger (), масштаб уменьшается. Я пробовал поиграть со всеми свойствами объекта геолокации, но ни одно из них не влияет на масштабирование, к которому идет функция trigger (), и, похоже, триггер не принимает никаких аргументов. Обратите внимание, что мне пришлось удалить свой mapboxgl.accessToken по соображениям безопасности. В качестве побочного примечания я также пытаюсь избавиться от большего синего круга уверенности в местоположении, но я также не могу этого сделать, несмотря на установку showAccuracyCircle: false. Есть какие-нибудь советы по mapbox?

React component:

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. Но затем он сразу же сосредотачивается на местоположении пользователя (это желаемое поведение) и уменьшает масштаб (я не хочу уменьшать масштаб). Чтобы увидеть это, вам необходимо предоставить кодовой странице разрешение на доступ к вашему местоположению.

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

Ответы [ 2 ]

1 голос
/ 04 августа 2020

Рискуя указать на очевидное, вы должны установить 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]}))
}
0 голосов
/ 06 августа 2020

Я нашел для этого немного другой обходной путь. Он использует 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}
  />
...