123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
- /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- /* eslint-disable react/jsx-sort-default-props, react/sort-prop-types */
- /* eslint-disable react/forbid-prop-types, react/require-default-props */
- import React from 'react';
- import PropTypes from 'prop-types';
- import MapGL from 'react-map-gl';
- import Immutable from 'immutable';
- import ViewportMercator from 'viewport-mercator-project';
- import ScatterPlotGlowOverlay from './ScatterPlotGlowOverlay';
- import './MapBox.css';
- const NOOP = () => {};
- export const DEFAULT_MAX_ZOOM = 16;
- export const DEFAULT_POINT_RADIUS = 60;
- const propTypes = {
- width: PropTypes.number,
- height: PropTypes.number,
- aggregatorName: PropTypes.string,
- clusterer: PropTypes.object,
- globalOpacity: PropTypes.number,
- hasCustomMetric: PropTypes.bool,
- mapStyle: PropTypes.string,
- mapboxApiKey: PropTypes.string.isRequired,
- onViewportChange: PropTypes.func,
- pointRadius: PropTypes.number,
- pointRadiusUnit: PropTypes.string,
- renderWhileDragging: PropTypes.bool,
- rgb: PropTypes.array,
- bounds: PropTypes.array
- };
- const defaultProps = {
- width: 400,
- height: 400,
- globalOpacity: 1,
- onViewportChange: NOOP,
- pointRadius: DEFAULT_POINT_RADIUS,
- pointRadiusUnit: 'Pixels'
- };
- class MapBox extends React.Component {
- constructor(props) {
- super(props);
- const {
- width,
- height,
- bounds
- } = this.props; // Get a viewport that fits the given bounds, which all marks to be clustered.
- // Derive lat, lon and zoom from this viewport. This is only done on initial
- // render as the bounds don't update as we pan/zoom in the current design.
- const mercator = new ViewportMercator({
- width,
- height
- }).fitBounds(bounds);
- const {
- latitude,
- longitude,
- zoom
- } = mercator;
- this.state = {
- viewport: {
- longitude,
- latitude,
- zoom
- }
- };
- this.handleViewportChange = this.handleViewportChange.bind(this);
- }
- handleViewportChange(viewport) {
- this.setState({
- viewport
- });
- const {
- onViewportChange
- } = this.props;
- onViewportChange(viewport);
- }
- render() {
- const {
- width,
- height,
- aggregatorName,
- clusterer,
- globalOpacity,
- mapStyle,
- mapboxApiKey,
- pointRadius,
- pointRadiusUnit,
- renderWhileDragging,
- rgb,
- hasCustomMetric,
- bounds
- } = this.props;
- const {
- viewport
- } = this.state;
- const isDragging = viewport.isDragging === undefined ? false : viewport.isDragging; // Compute the clusters based on the original bounds and current zoom level. Note when zoom/pan
- // to an area outside of the original bounds, no additional queries are made to the backend to
- // retrieve additional data.
- const bbox = [bounds[0][0], bounds[0][1], bounds[1][0], bounds[1][1]];
- const clusters = clusterer.getClusters(bbox, Math.round(viewport.zoom));
- return React.createElement(MapGL, _extends({}, viewport, {
- mapStyle: mapStyle,
- width: width,
- height: height,
- mapboxApiAccessToken: mapboxApiKey,
- onViewportChange: this.handleViewportChange
- }), React.createElement(ScatterPlotGlowOverlay, _extends({}, viewport, {
- isDragging: isDragging,
- locations: Immutable.fromJS(clusters),
- dotRadius: pointRadius,
- pointRadiusUnit: pointRadiusUnit,
- rgb: rgb,
- globalOpacity: globalOpacity,
- compositeOperation: "screen",
- renderWhileDragging: renderWhileDragging,
- aggregation: hasCustomMetric ? aggregatorName : null,
- lngLatAccessor: location => {
- const coordinates = location.get('geometry').get('coordinates');
- return [coordinates.get(0), coordinates.get(1)];
- }
- })));
- }
- }
- MapBox.propTypes = propTypes;
- MapBox.defaultProps = defaultProps;
- export default MapBox;
|