Прежде всего, если вы хотите следовать этой статье и, возможно, воссоздать карту Google с x количеством пользовательских маркеров карты… управление версиями имеет решающее значение. В настоящее время существует около трех из четырех различных пакетов Google Map React, поэтому я не совсем уверен, почему их так много. В любом случае, я использую google-maps-react, документация обширна, а функциональность компонентов карты и маркера обеспечивает большую гибкость и свободу.

Что касается других пакетов, google-map-response обновляется немного чаще, чем его партнер по множественному числу, google-maps-react. Однако после тщательного тестирования я определил, что google-maps-react 'более эффективен для обработки любого количества маркеров, превышающих 500. Хотя' google-map-react 'может иметь более отзывчивые алгоритмы наведения кластера маркеров, его способность отображать большое (500+) количество маркеров бледнеет по сравнению с' google-maps -react. 'Последний примечательный пакет, «react-google-maps' довольно устарел, но сам по себе не является устаревшим, я не тестировал этот пакет.

Компонент карты

Во-первых, будет полезно кратко рассказать о настройке базовой карты, прежде чем добавлять какие-либо маркеры карты. Опять же, документация очень проста, когда дело доходит до настройки, просто импортируйте компоненты и верните карту внутри функции рендеринга, как показано ниже. Мне нравится использовать компонент класса для карты и чистый компонент для маркеров (которые я объясню позже).

import React, { Component } from "react";
import {Map, Marker, GoogleApiWrapper} from 'google-maps-react';
export class BlogMap extends Component {
  render(){
    return(
      <div>
        <Map
          google={this.props.google}
          initialCenter={{
            lat: 40.854885,
            lng: -88.081807
          }}
          zoom={15}
        >
        </Map>
      </div>)
}
export default GoogleApiWrapper({
  apiKey: (YOUR_GOOGLE_API_KEY_GOES_HERE)
})(BlogMap)

Компонент «Карта» принимает различные свойства, но, в частности, «initialCenter» точно устанавливает, в каком месте будет открываться ваша карта. Параметр «zoom» также устанавливает начальный уровень масштабирования (насколько увеличено), когда установленное местоположение «initialCenter» будет отображаться на карте. Не забудьте включить свой ключ Google Maps Javascript API в свой GoogleApiWrapper или передать ключ в компонент Map напрямую как свойство apiKey. Наконец, по умолчанию включены все элементы управления картой.

Ниже представлен компонент Карта для моего приложения clyma. Обратите внимание, что не все эти свойства необходимы для визуализации тысяч маркеров - это только для демонстрации гибкости этого пакета и его компонента Map.

<Map
  ref={(map) => (this._map = map)}
  google={this.props.google}
  styles={this.state.mapStyle}
  disableDefaultUI={true}
  streetViewControl={true}
  zoomControl={true}
  mapTypeControl={true}
  mapTypeControlOptions={{
    position: this.props.google.maps.ControlPosition.TOP_CENTER,
  }}
  zoomControlOptions={{
    style: this.props.google.maps.ZoomControlStyle.DEFAUL,
    position: this.props.google.maps.ControlPosition.LEFT_CENTER,
  }}
  streetViewControlOptions={{
    position: this.props.google.maps.ControlPosition.LEFT_CENTER,
  }}
  initialCenter={searchCoords}
  center={this.state.coords}
  zoom={8}
>

Отрисовка маркеров по умолчанию и настраиваемых маркеров

Теперь, когда у нас есть карта, нам нужно заполнить эту карту маркерами! Но как?

import React, { Component } from "react";
import {Map, Marker, GoogleApiWrapper} from 'google-maps-react';
export class BlogMap extends Component {
render(){
    return(
      <div>
        <Map
          google={this.props.google}
          initialCenter={{
            lat: 40.854885,
            lng: -88.081807
          }}
          zoom={15}
        >
          <Marker
            position={{lat: 37.759703, lng: -122.428093}} />
          <Marker />
        </Map>
      </div>)
}
export default GoogleApiWrapper({
  apiKey: (YOUR_GOOGLE_API_KEY_GOES_HERE)
})(BlogMap)

Основной способ визуализации маркера по умолчанию с помощью «google-maps-react» - это реализация простого компонента Marker в качестве опоры для компонента Map. Этот метод отлично подходит для визуализации нескольких маркеров, и вы даже можете визуализировать множество маркеров за раз, сопоставив массив данных маркеров:

{this.markerData.map((marker)=>{
  return  <Marker
            position={{lat: marker.lat, marker.lng}} />
})}

В качестве реквизита мы можем настроить этот маркер по умолчанию, изменив значок на любое изображение, которое захотим. Ниже представлена ​​настройка пользовательского значка для clyma, который устанавливает для каждого маркера уникальный URL-адрес изображения для соответствующей оценки индекса качества воздуха. Обратите внимание, что точка привязки, размер и масштабированные размеры для пользовательского значка должны быть установлены в соответствии с размерами файла изображения значка. Другая информация, такая как id и обработчики событий, также передаются каждому компоненту Marker.

<Marker
  info={statObj}
  position={{ lat: statObj.lat, lng: statObj.lon }}
  id={statObj.uid}
  onMouseover={this.props.mouseEnterHandler}
  onMouseout={this.props.mouseLeaveHandler}
  {...this.props} 
  icon={{
    url: `https://waqi.info/mapicon/${statObj.aqi}.30.png`,
    anchor: new google.maps.Point(iw / 4, ih / 2 - 5),
    size: new google.maps.Size(iw / 2, ih / 2),
    scaledSize: new google.maps.Size(iw / 2, ih / 2),
  }}
/>

Отлично, теперь у нас есть куча маркеров, разбросанных по нашей карте Google. Однако… каждый раз, когда устанавливается или изменяется какая-либо часть состояния, компонент «Карта» будет повторно визуализироваться. Это связано с жизненным циклом React. Чтобы отображать тысячи маркеров, предотвращая повторную визуализацию указанных маркеров каждый раз при повторной визуализации компонента карты, рекомендуется чистый компонент. Это связано с тем, что чистые компоненты не зависят и не изменяют состояние каких-либо переменных, которые находятся за пределами их области. Чистый компонент имеет автоматический метод shouldComponentUpdate, который выполняет поверхностное сравнение данных состояния / свойств. Если данные маркера не изменились (предыдущее состояние и данные реквизита такие же, как и следующее состояние и реквизиты), то компонент не повторно визуализируется. Настроить чистый компонент очень просто!

Ниже представлена ​​структура чистого компонента, который я использовал для визуализации около 10 000 точек данных на карте Google с настраиваемым значком для каждого маркера карты. В этом примере я использую Redux для доступа к данным маркеров карты.

import React, { PureComponent } from "react";
import { connect } from "react-redux";
import { Marker } from "google-maps-react";
class Markers extends PureComponent {
  render() {
    const google = this.props.google;
    let iw = 70,
      ih = 94;
    return this.props.stats.map((statObj) => {
      if (statObj.aqi !== "-")
        return(
          <Marker
           info={statObj}
           position={{ lat: statObj.lat, lng: statObj.lon }}
           id={statObj.uid}
           onMouseover={this.props.mouseEnterHandler}
           onMouseout={this.props.mouseLeaveHandler}
           {...this.props}
           icon={{
            url: `https://waqi.info/mapicon/${statObj.aqi}.30.png`,
            anchor: new google.maps.Point(iw / 4, ih / 2 - 5),
            size: new google.maps.Size(iw / 2, ih / 2),
            scaledSize: new google.maps.Size(iw / 2, ih / 2),
          }}
        />);
    });
  }
}
const mapStateToProps = (state) => {
  return {stats: state.stats};
};
export default connect(mapStateToProps, null)(Markers);

Для реализации просто импортируйте чистый компонент в свой компонент Map:

import Markers from "./Markers";
import React, { Component } from "react";
import {Map, GoogleApiWrapper} from 'google-maps-react';
export class BlogMap extends Component {
render(){
    return(
      <div>
        <Map
          google={this.props.google}
          initialCenter={{
            lat: 40.854885,
            lng: -88.081807
          }}
          zoom={15}
        >
          <Markers
            onMouseover={this.mouseEnterHandler}
            onMouseout={this.mouseLeaveHandler}
          />
        </Map>
      </div>)
}
export default GoogleApiWrapper({
  apiKey: (YOUR_GOOGLE_API_KEY_GOES_HERE)
})(BlogMap)

Успех! Теперь пользователи могут просматривать карту Google и легко и плавно взаимодействовать с любым настраиваемым маркером карты. Компонент карты может постоянно перезагружаться, но сами маркеры не будут мешать функциональным возможностям карты с тысячами отдельных визуализаций.

Надеюсь, этот метод может помочь некоторым из вас, которым сложно отрендерить большое количество пользовательских маркеров карты. Не стесняйтесь обращаться ко мне в любое время для вопросов или помощи: linkedin | Twitter | Электронная почта | Гитхаб | "портфолио"