Подогнать карту к границам слоев объектов в листе реакции - PullRequest
0 голосов
/ 03 декабря 2018

Чего я хочу достичь:

Иметь иерархию <Map><FeatureGroup><Circle />[1 or more]...</FeatureGroup></Map> и подгонять границы карты к группе объектов так, чтобы все круги находились в области просмотра.

Если есть толькоодин круг, он должен соответствовать границам (то есть: увеличить) к этому кругу.

Что я пробовал:

  1. давая FeatureGroup a ref и вызываяgetBounds на нем, чтобы перейти на Map.Поскольку жизненный цикл FeatureGroup не существует во время вызова componentDidMount - он визуализируется позже (https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-161594328).
  2. Сохранение Circle в состоянии и вызов для него getBounds (при условии, что в этомслучай, что есть только один круг. Это тоже не сработало.

Я думаю, что, возможно, мне нужно что-то сделать с контекстом реакции, но я не уверен, что сейчас я полностью понимаю это, поэтому мне нужна помощь.

Другая информация

Я использую react-leaflet@2.1.2

Спасибо за любую помощь!

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Поскольку содержимое Map недоступно в componentDidMount время (https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-161594328), вы не можете получить границы FeatureGroup в этот момент и из всех refs, которые вы назначаете, только Map ссылка будет доступна в this.refs.

Однако, согласно этому комментарию GitHub: https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-366263225 вы можете дать FeatureGroup onAdd функцию обработчика:

<FeatureGroup ref="features" onAdd={this.onFeatureGroupAdd}>...

и затем вы можете использовать Map ссылки для доступа к leafletElement и вызова fitBounds с границами цели входящего события, которая будет FeatureGroup:

  onFeatureGroupAdd = (e) => {
    this.refs.map.leafletElement.fitBounds(e.target.getBounds());
  }

Это затем "масштабирует" карту в соответствии с вашими FeatureGroup, как вам нужно.

Обновление

Я изменил свой компонент React так, чтобы масштабирование и центр управлялисьпо параметрам запроса. Проблема с вышеупомянутым решением состояла в том, что если вы увеличите, например, MarkerClusterGroup, щелкнув по нему, он обновит масштаб в URL-адресе, повторно отобразит карту и повторно вызовет onFeatureGroupAdd, таким образом отменяя все качества кластера маркеров.

Мне нужно было получить доступ к уровню увеличенияМне нужно держать хорошо нарисованный круг в границах, затем обновить URL с правильным уровнем масштабирования и центром.

  onDrawCircle = (e) => {
    ...
    var targetZoom = this.refs.map.leafletElement.getBoundsZoom(e.layer.getBounds());
        // Call function to update url here:
        functionToUpdateUrl(targetZoom, e.layer.getBounds().getCenter());
    }
  }

Для того, чтобы иметь возможность контролировать всю карту, я также называю functionToUpdateUrl вОбработчики событий onZoomEnd и onDragEnd, например:

  onChangeView = (e) => {
      functionToUpdateUrl(e.target._zoom, this.refs.map.leafletElement.getCenter());
  }

и один для обработки щелчков кластера:

  onClusterClick = (e) => {
     // This time we want the center of the layer, not the map?
     functionToUpdateUrl(e.target._zoom, (e.layer ? e.layer.getBounds().getCenter() : e.target.getBounds().getCenter()));
  }

Затем при рендеринге элемента Map передайте следующие свойства:

  <Map
    center={center}
    ref='map'
    zoom={zoom}
    maxZoom={18}
    onZoomEnd={this.onChangeView}
    onDragEnd={this.onChangeView}
  >
  ....
  </Map>

И не забудьте дать любому MarkerClusterGroup s onClusterClick обратный вызов:

<MarkerClusterGroup onAdd={this.onMarkerGroupAdd} onClusterClick={this.onClusterClick}>
0 голосов
/ 04 декабря 2018

Вы пытались выполнить getBounds в функции componentDidMount вместо componentWillMount?Если это не сработает, я бы предложил расширить компонент FeatureGroup и добавить функцию onLoaded в качестве опоры и вызвать эту функцию в функции componentDidMount вашего расширенного компонента.И под расширением компонента FeatureGroup я имею в виду копирование / вставку его из здесь .(если вас волнует, почему вам нужно скопировать весь этот файл, проверьте этот поток)

Это не проверено, но ваш код, вероятно, будет выглядеть примерно так:

import { FeatureGroup } from 'leaflet';

import { withLeaflet, Path } from 'react-leaflet';

class CustomFeatureGroup extends Path {
  createLeafletElement(prop) {
    const el = new FeatureGroup(this.getOptions(props));
    this.contextValue = {
      ...props.leaflet,
      layerContainer: el,
      popupContainer: el,
    };
    return el;
  }

  componentDidMount() {
    super.componentDidMount();
    this.setStyle(this.props);
    /*
     Here you can do your centering logic with an onLoad callback or just
     by using this.leafletElement.map or whatever
    */
    this.props.onLoaded();
  }
}

export default withLeaflet(CustomFeatureGroup)

Примечание: если вы используете react-leaflet V1, это на самом деле намного проще, и я могу отредактировать этот ответ с помощью этого кода, если необходимо.

...