Я всегда любил карты. С самого детства я часами рассматривал глобусы и атласы. Карты привели к моей пожизненной любви к истории, так как мне было любопытно, как проходят эти границы и какой была и была жизнь людей в этих разных местах. Теперь я имел дело с двумя разными картографическими платформами и соответствующими библиотеками, используемыми для их рендеринга. Во-первых, я сделал индивидуальную историческую карту с помощью 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> }) }
Работа с картами может быть очень увлекательной. Они дают вам множество вариантов и обеспечивают потрясающую функциональность для любого приложения, к которому они относятся.