Skip to content

Commit

Permalink
migrate react-map-gl ControlScale
Browse files Browse the repository at this point in the history
  • Loading branch information
j8seangel committed Apr 16, 2024
1 parent 28d2d30 commit 318a6df
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 31 deletions.
7 changes: 5 additions & 2 deletions apps/fishing-map/features/map/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { DeckGL, DeckGLRef } from '@deck.gl/react'
import { LayersList } from '@deck.gl/core'
import dynamic from 'next/dynamic'
// import { atom, useAtom } from 'jotai'
import { ViewState } from 'react-map-gl'
import { RulersLayer } from '@globalfishingwatch/deck-layers'
import {
useIsDeckLayersLoading,
Expand All @@ -25,6 +24,7 @@ import { useMapRulersDrag } from 'features/map/overlays/rulers/rulers-drag.hooks
import ErrorNotification from 'features/map/overlays/error-notification/ErrorNotification'
import { useMapDeckLayers } from 'features/map/map-layers.hooks'
import MapPopups from 'features/map/popups/MapPopups'
import { MapCoordinates } from 'types'
import {
MAP_VIEW,
useViewStateAtom,
Expand All @@ -35,6 +35,7 @@ import styles from './Map.module.css'
import MapAnnotations from './overlays/annotations/Annotations'
import MapAnnotationsDialog from './overlays/annotations/AnnotationsDialog'
import useRulers from './overlays/rulers/rulers.hooks'
import MapInfo from './controls/MapInfo'

// This avoids type checking to complain
// https://github.com/visgl/deck.gl/issues/7304#issuecomment-1277850750
Expand All @@ -61,7 +62,7 @@ const MapWrapper = () => {
(params: any) => {
// add transitionDuration: 0 to avoid unresponsive zoom
// https://github.com/visgl/deck.gl/issues/7158#issuecomment-1329722960
setViewState({ ...(params.viewState as ViewState), transitionDuration: 0 })
setViewState({ ...(params.viewState as MapCoordinates), transitionDuration: 0 })
},
[setViewState]
)
Expand Down Expand Up @@ -315,6 +316,8 @@ const MapWrapper = () => {
{isWorkspace && !reportLocation && (
<Hint id="clickingOnAGridCellToShowVessels" className={styles.helpHintRight} />
)}
{/* TODO:deck pass hovered cursor coordinates */}
<MapInfo center={null} />
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@
transform: scale(0);
height: 0;
pointer-events: none;
transition:
transform 0.3s 0.5s,
border 0.3s 0s;
transition: transform 0.3s 0.5s, border 0.3s 0s;
margin-bottom: 0;
border: none;
}
Expand Down
4 changes: 2 additions & 2 deletions apps/fishing-map/features/map/controls/MapInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { useSelector } from 'react-redux'
import formatcoords from 'formatcoords'
import cx from 'classnames'
import { DateTime, DateTimeFormatOptions } from 'luxon'
import { ScaleControl } from 'react-map-gl'
import { InteractionEvent } from '@globalfishingwatch/react-hooks'
import { toFixed } from 'utils/shared'
import { useTimerangeConnect } from 'features/timebar/timebar.hooks'
import I18nDate from 'features/i18n/i18nDate'
import { selectShowTimeComparison } from 'features/reports/reports.selectors'
import styles from './MapInfo.module.css'
import MapScaleControl from './MapScaleControl'

export const pickDateFormatByRange = (start: string, end: string): DateTimeFormatOptions => {
const A_DAY = 1000 * 60 * 60 * 24
Expand Down Expand Up @@ -49,7 +49,7 @@ const MapInfo = ({ center }: { center: InteractionEvent | null }) => {
return (
<div className={styles.info}>
<div className={styles.flex}>
<ScaleControl maxWidth={100} unit="nautical" />
<MapScaleControl />
{center && (
<div className={cx('print-hidden', styles.mouseCoordinates)}>
{toFixed(center.latitude, 4)} {toFixed(center.longitude, 4)}
Expand Down
10 changes: 10 additions & 0 deletions apps/fishing-map/features/map/controls/MapScaleControl.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.scale {
position: absolute;
bottom: var(--space-M);
left: var(--space-S);
min-height: 1.5rem;
font: var(--font-XS);
background: none;
color: rgba(var(--white-rgb), 0.65);
border-bottom: 1px solid rgba(var(--white-rgb), 0.65);
}
52 changes: 52 additions & 0 deletions apps/fishing-map/features/map/controls/MapScaleControl.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useTranslation } from 'react-i18next'
import { distance as turfDistance } from '@turf/turf'
import { useMapViewport } from '../map-viewport.hooks'
import styles from './MapScaleControl.module.css'

// code from maplibre-gl-js
// https://github.com/maplibre/maplibre-gl-js/blob/d76c0447f49ddf9ea238ebe458b2488b03c0b361/src/ui/control/scale_control.ts

type ScaleControlProps = {
maxWidth?: number
}

function getDecimalRoundNum(d: number) {
const multiplier = Math.pow(10, Math.ceil(-Math.log(d) / Math.LN10))
return Math.round(d * multiplier) / multiplier
}

function getRoundNum(num: number) {
const pow10 = Math.pow(10, `${Math.floor(num)}`.length - 1)
let d = num / pow10

d = d >= 10 ? 10 : d >= 5 ? 5 : d >= 3 ? 3 : d >= 2 ? 2 : d >= 1 ? 1 : getDecimalRoundNum(d)

return pow10 * d
}

const NAUTICAL_MILE_UNIT = 1852

const MapScaleControl = ({ maxWidth = 100 }: ScaleControlProps) => {
const { t } = useTranslation()
const mapViewport = useMapViewport()

if (!mapViewport) {
return null
}

const y = mapViewport.height / 2
const left = mapViewport?.unproject([0, y])
const right = mapViewport?.unproject([maxWidth, y])
const maxMeters = turfDistance(left, right) * 1000
const maxDistance = maxMeters / NAUTICAL_MILE_UNIT
const distance = getRoundNum(maxDistance)
const ratio = distance / maxDistance

return (
<div className={styles.scale} style={{ width: `${maxWidth * ratio}px` }}>
{distance} {t(`map.nauticalMilesAbbr`, 'nm')}
</div>
)
}

export default MapScaleControl
12 changes: 0 additions & 12 deletions apps/fishing-map/features/map/map-layers.hooks.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,18 @@
import { useSelector } from 'react-redux'
import { useMemo } from 'react'
import { DataviewInstance } from '@globalfishingwatch/api-types'
import {
useDeckLayerComposer,
useDeckLayerLoadedState,
} from '@globalfishingwatch/deck-layer-composer'
import { useGlobalConfigConnect } from 'features/map/map.hooks'
import { selectHighlightedTime } from 'features/timebar/timebar.slice'
import { useHighlightedEventsConnect } from 'features/timebar/timebar.hooks'
import { selectDataviewInstancesResolvedVisible } from 'features/dataviews/selectors/dataviews.selectors'

export const useMapDeckLayers = () => {
const highlightedTime = useSelector(selectHighlightedTime)
const dataviews = useSelector(selectDataviewInstancesResolvedVisible)
const globalConfig = useGlobalConfigConnect()
const { highlightedEvents } = useHighlightedEventsConnect()
const params = useMemo(() => {
return {
highlightedTime,
highlightEventIds: highlightedEvents,
}
}, [highlightedEvents, highlightedTime])
const { layers } = useDeckLayerComposer({
dataviews: dataviews as DataviewInstance[],
globalConfig,
// params,
})

return layers
Expand Down
3 changes: 0 additions & 3 deletions apps/fishing-map/features/map/popups/PopupWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Fragment } from 'react'
import cx from 'classnames'
import { groupBy } from 'lodash'
import type { Anchor } from 'react-map-gl'
import { useSelector } from 'react-redux'
import { DataviewCategory } from '@globalfishingwatch/api-types'
import { Spinner } from '@globalfishingwatch/ui-components'
Expand Down Expand Up @@ -29,7 +28,6 @@ type PopupWrapperProps = {
closeOnClick?: boolean
className?: string
onClose?: () => void
anchor?: Anchor
type?: 'hover' | 'click'
}
function PopupWrapper({
Expand All @@ -39,7 +37,6 @@ function PopupWrapper({
type = 'hover',
className = '',
onClose,
anchor,
}: PopupWrapperProps) {
// Assuming only timeComparison heatmap is visible, so timerange description apply to all
const timeCompareTimeDescription = useTimeCompareTimeDescription()
Expand Down
10 changes: 1 addition & 9 deletions apps/fishing-map/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
import dynamic from 'next/dynamic'

const MapProvider = dynamic(() => import('react-map-gl').then((module) => module.MapProvider), {
ssr: false,
})

const AppNoSSRComponent = dynamic(() => import('../features/app/App'), {
ssr: false,
})

const Index = () => {
return (
<MapProvider>
<AppNoSSRComponent />
</MapProvider>
)
return <AppNoSSRComponent />
}

export default Index
1 change: 1 addition & 0 deletions apps/fishing-map/public/locales/source/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,7 @@
"loading": "Loading",
"lowRes": "See low resolution heatmaps",
"mapLoadingWait": "Please wait until map loads",
"nauticalMilesAbbr": "nm",
"rulers_add": "Add rulers",
"rulersStop": "Stop measures",
"rulersDelete": "Delete all measures",
Expand Down

0 comments on commit 318a6df

Please sign in to comment.