npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sk-global/hazard-risk

v0.3.2

Published

A TypeScript library for analyzing hazard risks and calculating risk assessments

Readme

Hazard Risk Analysis Library

A TypeScript library for analyzing disaster risk in any polygon area based on tile map data.

Features

  • ✅ Risk analysis in any polygon (GeoJSON)
  • Multiple hazard tile sources support with weighted risk calculation
  • ✅ Automatic grid generation with customizable resolution
  • ✅ Pixel reading from tile images (hazard map + base map)
  • ✅ Risk classification by RGB color
  • ✅ Water area exclusion
  • ✅ Detailed statistics calculation
  • ✅ Node.js environment support
  • ✅ TypeScript with full type safety
  • ✅ Tile caching with LRU algorithm
  • ✅ Concurrent tile preloading
  • ✅ Nearest point detection
  • ✅ Current location risk assessment
  • ✅ DEM elevation data extraction

Installation

npm install @sk-global/hazard-risk

Usage

Node.js Environment

import { analyzeRiskInPolygon, TileCache } from '@sk-global/hazard-risk';

// Create cache for better performance
const cache = new TileCache(200 * 1024 * 1024, 10 * 60 * 1000); // 200MB, 10 minutes

const polygon = {
  type: 'Polygon',
  coordinates: [[
    [141.3, 43.0], // bottom-left
    [141.4, 43.0], // bottom-right
    [141.4, 43.1], // top-right
    [141.3, 43.1], // top-left
    [141.3, 43.0]  // close polygon
  ]]
};

const result = await analyzeRiskInPolygon({
  polygon,
  hazardTiles: [
    {
      url: 'https://disaportaldata.gsi.go.jp/raster/01_flood_l1_shinsuishin_newlegend_data/{z}/{x}/{y}.png',
      weight: 1.0,
      priority: 1,
      name: 'Flood Risk'
    }
  ],
  baseTileUrl: 'https://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png',
  gridSize: 100, // 100 meters
  zoom: 12,
  currentLocation: { lat: 43.0619, lon: 141.3543 },
  mergeStrategy: 'max'
}, cache);

console.log('Risk statistics:', result.stats);
console.log('Total points:', result.total);
console.log('Water points:', result.waterCount);

Multiple Hazard Tiles Support

The library now supports analyzing risk from multiple hazard tile sources simultaneously with advanced merge strategies:

const result = await analyzeRiskInPolygon({
  polygon,
  hazardTiles: [
    {
      url: 'https://disaportaldata.gsi.go.jp/raster/01_flood_l1_shinsuishin_newlegend_data/{z}/{x}/{y}.png',
      weight: 1.0,
      priority: 1,
      name: 'Flood Risk'
    },
    {
      url: 'https://disaportaldata.gsi.go.jp/raster/02_tsunami_l2_shinsuishin_data/{z}/{x}/{y}.png',
      weight: 1.5,
      priority: 2,
      name: 'Tsunami Risk'
    },
    {
      url: 'https://disaportaldata.gsi.go.jp/raster/03_landslide_l1_shinsuishin_data/{z}/{x}/{y}.png',
      weight: 0.8,
      priority: 1,
      name: 'Landslide Risk'
    }
  ],
  baseTileUrl: 'https://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png',
  gridSize: 100,
  zoom: 12,
  mergeStrategy: 'max' // or 'average', 'weighted', 'priority'
});

Merge Strategies

  • max (default): Returns the highest risk level (safest approach, may have false positives)
  • average: Returns average risk level (balanced, good for reliable sources)
  • weighted: Returns weighted average based on provided weights
  • priority: Returns risk level from tile with highest priority

Advanced Usage with Custom Hazard Configuration

import { createHazardConfig, analyzeRiskInPolygon } from '@sk-global/hazard-risk';

// Create custom hazard configuration
const tsunamiConfig = createHazardConfig('Tsunami Depth', {
  0: { name: 'level0', color: '#FFFFFF', description: '0m' },
  1: { name: 'level1', color: '#FFFFB3', description: '<0.3m' },
  2: { name: 'level2', color: '#F7F5A9', description: '<0.5m' },
  3: { name: 'level3', color: '#F8E1A6', description: '0.5~1m' },
  4: { name: 'level4', color: '#FFD8C0', description: '0.5~3m' },
  5: { name: 'level5', color: '#FFB7B7', description: '3~5m' },
  6: { name: 'level6', color: '#FF9191', description: '5~10m' },
  7: { name: 'level7', color: '#F285C9', description: '10~20m' },
  8: { name: 'level8', color: '#DC7ADC', description: '>20m' }
}, ['#bed2ff', '#f7f5a9', '#8bb8ff', '#6aa8ff']);

const result = await analyzeRiskInPolygon({
  polygon,
  hazardTiles: [
    {
      url: 'https://disaportaldata.gsi.go.jp/raster/01_flood_l1_shinsuishin_newlegend_data/{z}/{x}/{y}.png',
      weight: 1.0,
      priority: 1,
      name: 'Flood Risk'
    },
    {
      url: 'https://disaportaldata.gsi.go.jp/raster/02_tsunami_l2_shinsuishin_data/{z}/{x}/{y}.png',
      weight: 1.5,
      priority: 2,
      name: 'Tsunami Risk'
    }
  ],
  baseTileUrl: 'https://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png',
  gridSize: 100,
  zoom: 12,
  hazardConfig: tsunamiConfig,
  currentLocation: { lat: 43.0619, lon: 141.3543 },
  mergeStrategy: 'weighted'
});

Results

Node.js Result Structure

{
  stats: {
    '0': 2174,    // Level 0 - No risk
    '2': 1294,    // Level 2 - Warning
    '4': 917,     // Level 4 - Moderate risk
    '5': 11,      // Level 5 - High risk
    '6': 2,       // Level 6 - Very high risk
    total: 4398   // Total points analyzed
  },
  nearestPoints: {
    '0': { latitude: 43.0616, longitude: 141.3538, distance: 56.56 },
    '2': { latitude: 43.0623, longitude: 141.3538, distance: 56.56 },
    // ... nearest points for each risk level
  },
  waterCount: 0,
  currentLocationRisk: { riskLevel: 2, isWater: false },
  hazardConfig: { /* hazard configuration */ }
}

API Reference

analyzeRiskInPolygon(options, cache?)

Analyze risk in polygon for Node.js environment.

Parameters:

  • options.polygon: GeoJSON Polygon
  • options.hazardTiles: Array of hazard tile configurations
    • url: URL template for hazard tiles
    • weight?: Weight for this hazard (default: 1)
    • priority?: Priority for this hazard (default: 1)
    • name?: Optional name for this hazard source
    • type?: Optional type for this hazard source
  • options.baseTileUrl: URL template for base tiles
  • options.gridSize: Distance between grid points (meters)
  • options.zoom: Tile zoom level
  • options.hazardConfig?: Custom hazard configuration
  • options.currentLocation?: Current location for nearest point detection
  • options.mergeStrategy?: Strategy to merge risk levels ('max', 'average', 'weighted', 'priority')
  • cache?: Optional TileCache instance

TileCache(maxSize, ttl)

LRU cache for tile images.

Parameters:

  • maxSize: Maximum cache size in bytes
  • ttl: Time to live in milliseconds

createHazardConfig(name, levels, waterColors?)

Create custom hazard configuration.

Parameters:

  • name: Hazard name
  • levels: Risk level configuration object
  • waterColors?: Array of water color hex codes

getElevationFromDEM(options)

Get elevation data from DEM tiles for Node.js environment.

Parameters:

  • options.lat: Latitude
  • options.lng: Longitude
  • options.zoom?: Zoom level (default: 17)
  • options.demConfigs?: Custom DEM configurations
  • options.cache?: Optional TileCache instance

Returns:

{
  elevation: number | null,
  source: string,
  fixed: number,
  position: { lat: number, lng: number, zoom: number }
}

DEM Elevation Data

The library supports extracting elevation data from DEM (Digital Elevation Model) tiles. Default configurations support GSI Japan DEM services:

| DEM Type | Zoom Level | Precision | Description | |----------|------------|-----------|-------------| | DEM1A | 17 | 0.1m | Highest precision | | DEM5A | 15 | 0.1m | High precision | | DEM5B | 15 | 0.1m | High precision | | DEM5C | 15 | 0.1m | High precision | | DEM10B | 14 | 1m | Standard precision |

Example Usage

import { getElevationFromDEM } from '@sk-global/hazard-risk';

// Get elevation for Tokyo
const result = await getElevationFromDEM({
  lat: 35.6762,
  lng: 139.6503,
  zoom: 17
});

if (result.elevation !== null) {
  console.log(`Elevation: ${result.elevation.toFixed(result.fixed)}m`);
  console.log(`Source: ${result.source}`);
} else {
  console.log('No elevation data found');
}

Risk Classification

The library supports dynamic risk classification based on RGB colors. Default tsunami configuration:

| Color (RGB) | Level | Description | |-------------|-------|-------------| | 255,255,255 | 0 | No risk | | 255,255,179 | 1 | Attention | | 247,245,169 | 2 | Warning | | 248,225,166 | 3 | Moderate risk | | 255,216,192 | 4 | High risk | | 255,183,183 | 5 | Very high risk | | 255,145,145 | 6 | Extreme risk | | 242,133,201 | 7 | Critical risk | | 220,122,220 | 8 | Maximum risk |

Environment Support

  • Node.js: Full support with PNG processing via pngjs
  • TypeScript: Complete type definitions
  • AWS Lambda: Optimized for serverless environments

Dependencies

  • @turf/turf: Polygon processing, bounding box calculations
  • pngjs: PNG image processing (Node.js)
  • axios: HTTP requests for tile fetching

Performance Features

  • Tile Caching: LRU cache with configurable size and TTL
  • Concurrent Loading: Parallel tile fetching with rate limiting
  • Grid Optimization: Efficient point grid generation with polygon masking
  • Memory Management: Automatic cache eviction and memory cleanup

Examples

See the example.ts file for a complete working example using GSI Japan tsunami data.

License

MIT