Two Views
The application provides two different map views via path-based routing:- Isometric View (
/) - OpenSeadragon-based deep-zoom rendering of the pixel-art isometric NYC map by @cannoneyed - Map View (
/map) - MapLibre GL-based traditional 2D slippy map with CartoDB dark tiles
The isometric view (App.tsx) is the primary interface and is described in detail on this page. For the alternative map view implementation, see PermitMap Component.
Tech Stack
The application is built with:- React - UI components and state management
- Vite - Fast build tool and dev server
- TypeScript - Type-safe development
- OpenSeadragon - Deep-zoom tile viewer for the isometric map
- MapLibre GL - WebGL-based map rendering for the alternative map view
- react-window - Virtualized permit list for performance
Component Structure
The application follows a single-file component architecture centered aroundApp.tsx:
Core Components
App
Main container - manages OpenSeadragon viewer, permit data fetching, filtering, and overlay rendering
PermitDrawer
Slide-in detail panel showing full permit information, owner/contractor details, and external links
PermitRow
Virtualized list item for the sidebar permit list - renders type, address, and date
PermitChart
Bar chart breakdown of permit types in the current filter set
Helper Components
NeighborhoodLabels component provides three zoom levels:
- Borough level - 5 major boroughs at low zoom
- Major neighborhoods - ~30 prominent areas at medium zoom
- All NTAs - 197 neighborhood tabulation areas at high zoom
State Management
The app uses React hooks for local state - no external state management library. All state is managed inApp.tsx:
Filter State Interface
Data Flow
The application follows a unidirectional data flow:Render Markers
placeMarkers() converts lat/lng to image pixels and adds OpenSeadragon overlays in chunksData Fetching
Permits are fetched on mount and refreshed every 5 minutes:Performance Optimizations
Chunked Marker Rendering
To avoid blocking the main thread, markers are added in chunks of 400 per frame usingrequestAnimationFrame:
Pre-computed Opacity Values
Recency fade is calculated once for all permits in O(n) instead of O(n²):Virtualized List
The sidebar permit list usesreact-window to only render visible items:
OpenSeadragon Integration
The isometric map is rendered using OpenSeadragon’s Deep Zoom Image (DZI) format with custom tile sources:Critical OSD Viewport Coordinates
File Structure
Next Steps
Data Sources
Learn about the NYC Open Data integration
Coordinate Projection
Understand the isometric projection math
Permit Types
Explore all 18+ permit type codes and colors
Development
Set up your local development environment