UNPKG

@gooddata/react-components

Version:

GoodData.UI - A powerful JavaScript library for building analytical applications

94 lines (82 loc) 2.67 kB
// (C) 2020 GoodData Corporation import get = require("lodash/get"); import mapboxgl = require("mapbox-gl"); import { DEFAULT_CENTER, DEFAULT_WORLD_BOUNDS, DEFAULT_ZOOM, VIEWPORTS } from "../../constants/geoChart"; import { IGeoConfig, IGeoConfigViewport, IGeoLngLat, IGeoLngLatBounds } from "../../interfaces/GeoChart"; interface IGeoViewport { bounds?: mapboxgl.LngLatBoundsLike; center?: IGeoLngLat; zoom?: number; } export function getViewportOptions(data: IGeoLngLat[], config: IGeoConfig): IGeoViewport { const center: IGeoLngLat = get<IGeoConfig, "center">(config, "center"); const zoom: number = get<IGeoConfig, "zoom", number>(config, "zoom", DEFAULT_ZOOM); const { area }: IGeoConfigViewport = get<IGeoConfig, "viewport", {}>(config, "viewport", {}); // use `center` config if it exists if (!center) { if (VIEWPORTS[area]) { return { bounds: VIEWPORTS[area], }; } else { const lngLatBounds: IGeoLngLatBounds = getLngLatBounds(data); if (lngLatBounds) { return { bounds: [lngLatBounds.northEast, lngLatBounds.southWest], }; } return { center: DEFAULT_CENTER, zoom, }; } } return { center, zoom, }; } /* * @method getLngLatBounds: IGeoLngLatBounds * Represents a rectangular geographical area on a map. * * @example * * ```js * const corner1 = [40.712, -74.227], * const corner2 = [40.774, -74.125], * const bounds = getLngLatBounds([corner1, corner2]); * * bounds && map.fitBounds([bounds.northEast, bounds.southWest], { padding: 60 }); * ``` */ export function getLngLatBounds(lnglats: IGeoLngLat[]): IGeoLngLatBounds { if (!lnglats || !lnglats.length) { return; } return lnglats.reduce(extendLngLatBounds, undefined) || DEFAULT_WORLD_BOUNDS; } // @method extendLngLatBounds: IGeoLngLatBounds // Extend the bounds to contain the given point function extendLngLatBounds(bounds: IGeoLngLatBounds, lnglat: IGeoLngLat): IGeoLngLatBounds { if (!lnglat) { return bounds; } if (!bounds) { return { northEast: lnglat, southWest: lnglat, }; } const { northEast, southWest } = bounds; return { northEast: { lat: Math.max(lnglat.lat, northEast.lat), lng: Math.max(lnglat.lng, northEast.lng), }, southWest: { lat: Math.min(lnglat.lat, southWest.lat), lng: Math.min(lnglat.lng, southWest.lng), }, }; }