diff --git a/app/scripts/components/common/mapbox/layers/utils.ts b/app/scripts/components/common/mapbox/layers/utils.ts index d7300b357..97fecce74 100644 --- a/app/scripts/components/common/mapbox/layers/utils.ts +++ b/app/scripts/components/common/mapbox/layers/utils.ts @@ -1,7 +1,7 @@ import { FunctionComponent, useEffect } from 'react'; import { Feature } from 'geojson'; import { Map as MapboxMap } from 'mapbox-gl'; -import { defaultsDeep } from 'lodash'; +import { defaultsDeep, clamp } from 'lodash'; import axios, { Method } from 'axios'; import { eachDayOfInterval, @@ -372,30 +372,6 @@ export function getMergedBBox(features: StacFeature[]) { export const FIT_BOUNDS_PADDING = 32; -export function checkFitBoundsFromLayer( - layerBounds?: [number, number, number, number], - mapInstance?: MapboxMap -) { - if (!layerBounds || !mapInstance) return false; - - const [minXLayer, minYLayer, maxXLayer, maxYLayer] = layerBounds; - const [[minXMap, minYMap], [maxXMap, maxYMap]] = mapInstance - .getBounds() - .toArray(); - const isOutside = - maxXLayer < minXMap || - minXLayer > maxXMap || - maxYLayer < minYMap || - minYLayer > maxYMap; - const layerExtentSmaller = - maxXLayer - minXLayer < maxXMap - minXMap && - maxYLayer - minYLayer < maxYMap - minYMap; - - // only fitBounds if layer extent is smaller than viewport extent (ie zoom to area of interest), - // or if layer extent does not overlap at all with viewport extent (ie pan to area of interest) - return layerExtentSmaller || isOutside; -} - interface LayerInteractionHookOptions { layerId: string; mapInstance: MapboxMap; @@ -434,6 +410,25 @@ export function useLayerInteraction({ type OptionalBbox = number[] | undefined | null; +/** + * MapboxGL requires maxX value to be 180, minX -180, maxY 90, minY -90 + * While some of the datasets having bbox going above it. + * @param bounds Bounding box to fit layer + * @returns Boolean + */ + +function clampBbox( + bounds: [number, number, number, number] +): [number, number, number, number] { + const [minX, minY, maxX, maxY] = bounds; + return [ + clamp(minX, -180, 180), + clamp(minY, -90, 90), + clamp(maxX, -180, 180), + clamp(maxY, -90, 90) + ]; +} + /** * Centers on the given bounds if the current position is not within the bounds, * and there's no user defined position (via user initiated map movement). Gives @@ -458,8 +453,9 @@ export function useFitBbox( | [number, number, number, number] | undefined; - if (bounds?.length && checkFitBoundsFromLayer(bounds, mapInstance)) { - mapInstance.fitBounds(bounds, { padding: FIT_BOUNDS_PADDING }); + if (bounds?.length) { + const clampedBbox = clampBbox(bounds); + mapInstance.fitBounds(clampedBbox, { padding: FIT_BOUNDS_PADDING }); } }, [mapInstance, isUserPositionSet, initialBbox, stacBbox]); }