Map Components

Leaflet, deck.gl, and custom map components for geo-spatial visualization — heatmaps, geofences, animated timelines, and floor plan overlays.

Last updated: 2025-02-18

Map Components

Certexi's map system provides a rich set of components for rendering logistics events, warehouse geofences, and animated timelines on interactive maps.

certexi.com/app/geo/heatmap
Loading interactive demo...

Dot density map — 500 logistics events across warehouse hubs with type filtering.

Component Inventory

ComponentTechnologyDescription
EventsMapdeck.glPrimary map with ScatterplotLayer, HeatmapLayer, TextLayer
WhmsGeofenceMapLeafletWarehouse geofence polygons with click-to-drill
FloorPlanCanvasKonva.jsIndoor floor plan with polygon slot overlays
TimeNavigatorReactTime window control with presets and live mode
GeoTimelinePlayerdeck.glAnimated event playback with scrubber

Animated Timeline

Watch logistics events unfold over time. The timeline scrubber enables jumping to any moment in a 48-hour window.

certexi.com/app/geo/timeline
Loading interactive demo...

48-hour animated playback with speed controls from 0.5x to 4x.

Geofence Polygons

Define warehouse boundaries as polygons. Click any zone to see utilization metrics and drill into slot-level detail.

certexi.com/app/geo/geofence
Loading interactive demo...

5 warehouse geofences with capacity, utilization, and zone type metadata.

Map Controls

<Card className="w-80">
  <CardHeader className="pb-2">
    <CardTitle className="text-sm">Map Controls</CardTitle>
    <CardDescription>Time window and display options</CardDescription>
  </CardHeader>
  <CardContent className="space-y-3">
    <div className="flex gap-1 flex-wrap">
      <Badge variant="outline" className="cursor-pointer">1h</Badge>
      <Badge variant="outline" className="cursor-pointer">3h</Badge>
      <Badge className="bg-blue-500 text-white cursor-pointer">6h</Badge>
      <Badge variant="outline" className="cursor-pointer">12h</Badge>
      <Badge variant="outline" className="cursor-pointer">24h</Badge>
      <Badge variant="outline" className="cursor-pointer">7d</Badge>
    </div>
    <div className="space-y-1.5">
      <div className="flex justify-between text-xs">
        <span className="text-muted-foreground">Display Mode</span>
      </div>
      <div className="flex gap-1">
        <Button size="sm" variant="outline" className="flex-1 text-xs h-7">Points</Button>
        <Button size="sm" className="flex-1 text-xs h-7">Heatmap</Button>
        <Button size="sm" variant="outline" className="flex-1 text-xs h-7">Clusters</Button>
      </div>
    </div>
    <div className="flex items-center justify-between text-xs">
      <span className="text-muted-foreground">Events in view</span>
      <Badge variant="secondary">2,847</Badge>
    </div>
  </CardContent>
</Card>

Rendering Modes

The map automatically selects the optimal rendering mode based on event density:

Event CountModeTechnologyPerformance
< 10,000PointsScatterplotLayer~50ms render
10k-50kClustersGrouped markers~150ms render
50k+HeatmapGPU HeatmapLayer~200ms render
ℹ️

Zero DOM Markers

All rendering uses deck.gl WebGL layers. No DOM-based markers means zero React re-renders during pan and zoom operations.

Event Card

Each map event can be inspected with full metadata:

<Card className="w-72">
  <CardHeader className="pb-2">
    <div className="flex items-center justify-between">
      <Badge className="bg-blue-500 text-white text-[10px]">ENTRY</Badge>
      <span className="text-[10px] text-muted-foreground font-mono">14:32:07 UTC</span>
    </div>
    <CardTitle className="text-sm mt-1">TU-2025-00042</CardTitle>
    <CardDescription>Carlos Mendez — Warehouse Alpha</CardDescription>
  </CardHeader>
  <CardContent className="space-y-2">
    <div className="flex justify-between text-xs">
      <span className="text-muted-foreground">Location</span>
      <span className="font-mono">25.6714, -100.3097</span>
    </div>
    <div className="flex justify-between text-xs">
      <span className="text-muted-foreground">Evidence</span>
      <span>3 photos, 1 scan</span>
    </div>
    <div className="flex gap-1 pt-1">
      <Button size="sm" variant="outline" className="flex-1 text-xs h-7">Details</Button>
      <Button size="sm" className="flex-1 text-xs h-7">Timeline</Button>
    </div>
  </CardContent>
</Card>

Integration

import { EventsMap } from '@/components/whms/EventsMap';
import { TimeNavigator } from '@/components/whms/TimeNavigator';
import { WhmsGeofenceMap } from '@/components/whms/WhmsGeofenceMap';

// Compose map with time controls
<div className="flex flex-col h-screen">
  <TimeNavigator
    onTimeWindowChange={setTimeWindow}
    presets={['1h', '3h', '6h', '12h', '24h']}
  />
  <EventsMap
    events={events}
    timeWindow={timeWindow}
    renderMode="auto"
  />
</div>