Skip to content

Commit

Permalink
fix: fitBounds on non-Mercator projections
Browse files Browse the repository at this point in the history
fitBounds was behaving erratically on map projections other than
Mercator. This adds a "center" geometry, calculated from the new visible
points, to ensure that the map doesn't go galloping off the edge of the
world.
  • Loading branch information
lauramosher committed Jul 13, 2023
1 parent 6905ec6 commit 8b98900
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 9 deletions.
23 changes: 23 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@turf/bbox": "^6.5.0",
"@turf/center": "^6.5.0",
"@turf/helpers": "^6.5.0",
"@types/jest": "^27.5.2",
"@types/mapbox-gl": "^2.7.11",
"@types/node": "^16.18.7",
Expand Down
24 changes: 16 additions & 8 deletions src/contexts/MapContext.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import { createContext, useContext, useState, ReactNode } from 'react'

import type { LngLatBoundsLike } from 'mapbox-gl'
import type { LngLatLike, LngLatBoundsLike } from 'mapbox-gl'
import type { GeoJsonProperties, Feature, Point } from 'geojson'

import bbox from '@turf/bbox'
import center from '@turf/center'
import {featureCollection} from '@turf/helpers'

type MapBounds = {
bounds: LngLatBoundsLike,
center: LngLatLike
}

interface MapConfig {
points: Array<Feature<Point, GeoJsonProperties>>
stashedPoints: Array<Feature<Point, GeoJsonProperties>> | undefined
setStashedPoints: (points: Array<Feature<Point, GeoJsonProperties>> | undefined) => void
updateStoryPoints: (newPoints: Array<Feature<Point, GeoJsonProperties>>) => void
bounds?: LngLatBoundsLike
bounds?: MapBounds
}

const MapContext = createContext<MapConfig>({
Expand All @@ -24,15 +32,15 @@ export const MapContextProvider = ({ children, initialPoints }: {children: React
const [points, setPoints] = useState<Array<Feature<Point, GeoJsonProperties>>>(initialPoints)
const [stashedPoints, setStashedPoints] = useState<Array<Feature<Point, GeoJsonProperties>>>()

const [bounds, setBounds] = useState<LngLatBoundsLike>()
const [bounds, setBounds] = useState<MapBounds>()

function updateStoryPoints(newPoints: Array<Feature<Point, GeoJsonProperties>>) {
setPoints(newPoints)
const bounds = {
type: 'FeatureCollection',
features: newPoints
}
setBounds(bbox(bounds) as LngLatBoundsLike)
const bounds = featureCollection(newPoints)
setBounds({
bounds: bbox(bounds) as LngLatBoundsLike,
center: center(bounds).geometry.coordinates as LngLatLike
})
}

return (
Expand Down
2 changes: 1 addition & 1 deletion src/pages/community/components/Map/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ export default function Map({config}: {config: MapData}) {
if (!mapRef.current) return
const map = mapRef.current
if (bounds) {
map.fitBounds(bounds, {padding: 50, duration: 2000.0, maxZoom: 12})
map.fitBounds(bounds.bounds, {center: bounds.center, padding: 50, duration: 2000.0, maxZoom: 12})
}
}, [bounds])

Expand Down

0 comments on commit 8b98900

Please sign in to comment.