Skip to content

runsascoded/deck-map

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@rdub/deck-map

Shared deck.gl + MapLibre map utilities, extracted across runsascoded map projects so each stops hand-rolling the same pieces.

Status: proof-of-concept (0.0.x). Only the lowest-risk, genuinely duplicated pieces are here so far — see Roadmap.

Why

Four sibling projects render interactive maps; three are deck.gl:

Project Engine deck.gl 3D Choropleth layer Basemap
jc-taxes deck.gl + MapLibre 9.x yes GeoJsonLayer extruded MapLibre / CARTO vector
crashes deck.gl + MapLibre 8.9 yes ColumnLayer (H3 hexes) MapLibre / Stadia raster
household-vehicles deck.gl 9.x yes GeoJsonLayer extruded deck.gl TileLayer / Stadia
ctbk Leaflet no Circle / Polyline Leaflet / Stadia raster

They're divergent enough that a single <ChoroplethMap> component would be a leaky abstraction — extruded-polygon vs. H3-column maps are different shapes. So this is a toolkit of small generic pieces, not one mega-component.

The clearest evidence it's worth extracting: useTouchPitch is currently byte-identical in jc-taxes and crashes.

Install

pnpm add @rdub/deck-map

react is an (optional) peer dependency — only useTouchPitch needs it.

API

useTouchPitch

Two-finger vertical-drag → pitch gesture for deck.gl on touch devices, working around deck.gl#4853 (pinch beats two-finger-pan). Operates on a controlled viewState. Takes a plain (next) => void setter — so it works with React useState and with non-updater setters like use-prms' useUrlState.

import { useTouchPitch } from '@rdub/deck-map'

const isPitchingRef = useTouchPitch({ viewState, setViewState, maxPitch: 85 })

<DeckGL
  viewState={viewState}
  onViewStateChange={({ viewState: vs }) => {
    if (isPitchingRef.current) return  // ignore deck.gl echoes during pitch
    setViewState(vs)
  }}
  controller={{ touchRotate: true }}
/>

Basemap presets

Theme-aware ('light' | 'dark') basemap config — stop copy-pasting alidade_smooth[_dark] URLs.

import { stadiaTileUrl, stadiaRasterStyle, cartoVectorStyleUrl } from '@rdub/deck-map'

stadiaTileUrl('dark')                       // deck.gl TileLayer `data`
stadiaRasterStyle('dark')                   // MapLibre <Map mapStyle={...}>
cartoVectorStyleUrl('light')                // CARTO vector style URL

Roadmap

Phased, low-risk first:

  • P1 (in progress)useTouchPitch, basemap presets. Next: camera helpers (fitBounds, metersPerPixel), a resizable-map container hook (drag-resize + sessionStorage height + reset), a pitch-slider widget.
  • P2 — a thin <DeckMap> shell: <DeckGL> + MapLibre basemap + controlled viewState + useTouchPitch wired in; consumers pass their own layers. Migrate household-vehicles and jc-taxes.
  • P3 — upgrade crashes from deck.gl 8.9 → 9.x, then migrate it.
  • P4 (optional)ctbk off Leaflet onto deck.gl — a rewrite, separate call.

Camera URL-param sync is intentionally out of scopeuse-prms's viewStateParam already covers it; consumers should adopt that directly.

Develop

pnpm install
pnpm build       # tsup → dist/ (ESM + CJS + d.ts)
pnpm test        # vitest
pnpm typecheck   # tsc --noEmit

About

Shared deck.gl + MapLibre React map utilities (touch-pitch, basemap presets)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors