Я всегда любил карты. С самого детства я часами рассматривал глобусы и атласы. Карты привели к моей пожизненной любви к истории, так как мне было любопытно, как проходят эти границы и какой была и была жизнь людей в этих разных местах. Теперь я имел дело с двумя разными картографическими платформами и соответствующими библиотеками, используемыми для их рендеринга. Во-первых, я сделал индивидуальную историческую карту с помощью Mapbox, которую я отрендерил и добавил функциональность с помощью библиотеки Uber React-Map-GL. Недавно я провел некоторое время, помогая другу с картой Google, он хотел отобразить список организаций, используя библиотеку Google-Maps-React. Имея в виду этот опыт, я хотел бы поделиться некоторыми мыслями о работе с картами.

Карты немного отличаются от рендеринга текста или других данных HMTL. Вам нужно найти исходную карту или создать свою собственную. Существует ряд платформ, позволяющих создавать собственные карты, среди наиболее известных — Leaflet и Mapbox. Google Maps API также позволяет в значительной степени стилизовать. По моему опыту, Mapbox наиболее надежен с точки зрения создания пользовательских карт и визуализации данных. Тогда возникает вопрос, как вывести карту на экран. В Mapbox и Leaflet это делается просто путем передачи URL-адреса вашей карты в компонент, например (в ближайшее время я расскажу о некоторых других аспектах этого кода):

<MapGL
   {…viewport}
   width=”100%”
   height=”350px”
   onViewportChange={this.updateViewport}
   mapStyle={selectedMap.url}
   onClick={this.onMapClci}
   mapboxApiAccessToken={TOKEN}
>
   {this.renderMarkers()}
   {this.renderPopup()}
   <div className=”nav” style={navStyle}>
      <NavigationControl onViewportChange={this.updateViewport} />
   </div>
</MapGL>

В библиотеке Google-Maps-React это делается с помощью компонента более высокого порядка — компонента, который получает компонент в качестве аргумента и возвращает компонент, обычно с добавленными свойствами, такими как подключение к магазину Redux или макет по умолчанию — который подключен обеспечивает карту через Google API, см. пример ниже:

GoogleApiWrapper({
   apiKey: __GAPI_KEY__,
   libraries: [‘places’, ‘visualization’],
   LoadingContainer: Loading
})(Container)

После того, как ваша карта появится на странице, вы, как правило, захотите что-нибудь с ней сделать! Здесь есть масса вариантов в зависимости от вашего проекта, но я расскажу только о некоторых из тех, с которыми имел дело. Во-первых, возникает вопрос установки начального местоположения карты и придания ей интерактивности. Начальное местоположение — с точки зрения широты, долготы и масштаба — обычно задается в конструкторе компонента вашей карты, например так:

state = {
   viewport: {
      latitude: 49.5,
      longitude: -1.25,
      zoom: 3.5,
   }
}

или в компоненте карты, взятом из библиотеки, которую вы используете:

<Map
   google={this.props.google}
   initialCenter={{
      lat: 40.854885,
      lng: -88.081807
   }}
   zoom={15}
>

Что касается интерактивности, то создается функция обратного вызова, которая передается какому-то обработчику событий в самой карте. В соответствии с примерами выше, давайте посмотрим на пример этого в Mapbox:

updateViewport = (viewport) => {
   this.setState({viewport});
}

И для гугл карт.

onMapReady = (mapProps, map) => {
   this.map = map;
   window.onresize = () => {
      const currCenter = map.getCenter();
      this.props.google.maps.event.trigger(map, ‘resize’);
      map.setCenter(currCenter);
   };
};

Как и все в React, представление является функцией состояния. Поскольку события вызывают изменение состояния карты, само представление обновляется.

Наконец, давайте немного поговорим о маркерах рендеринга. Что вам нужно для каждого маркера, который вы хотите визуализировать, так это широта и долгота, обычно в качестве ключей к объекту, представляющему то, чем должен быть маркер. Затем вы используете метод рендеринга для сопоставления указанных объектов и рендеринга списка маркеров на карте. Этим маркерам также можно передавать события щелчка, чтобы делать такие вещи, как создание всплывающих окон или предоставление дополнительной информации о том, что находится в этом маркере на боковой панели:

renderMarkers = () => {
   const {selectedMap} = this.props
   return selectedMap.historical_events.map(historicalEvent => {
   <Marker
      key={historicalEvent.id}
      latitude={historicalEvent.latitude}
      longitude={historicalEvent.longitude}
   >
      <Pin handlePinClick={() =>    this.handlePinClick(historicalEvent)}/>
  </Marker>
  })
}

Работа с картами может быть очень увлекательной. Они дают вам множество вариантов и обеспечивают потрясающую функциональность для любого приложения, к которому они относятся.