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

odraw-symbols

v1.0.1

Published

Comprehensive orienteering map symbol library supporting ISOM, ISSkiOM, ISMTBOM, and Course Design standards

Readme

@odraw/symbols

Comprehensive orienteering map symbol library for JavaScript/TypeScript

A complete, type-safe library of orienteering map symbols supporting ISOM, ISSkiOM, ISMTBOM, ISSprOM, ISSOM, and Course Design standards. Perfect for building orienteering mapping tools, course planning applications, and map visualization software.

Features

  • Complete Symbol Coverage - All ISOM 2017-2 symbols plus specialized standards
  • Multiple Standards - ISOM, ISSkiOM, ISMTBOM, ISSprOM, ISSOM, Course Design
  • Multiple Scales - Support for 1:4000, 1:5000, 1:7500, 1:10000, 1:12500, 1:15000, 1:20000
  • Actual SVG Geometry - Extracts real symbol shapes from .omap files
  • Individual SVG Files - Each symbol exported as standalone SVG with metadata
  • Type-Safe - Full TypeScript support with comprehensive type definitions
  • Smart Categorization - Symbols organized by category (Landforms, Water, Vegetation, etc.)
  • Flexible Filtering - Filter by standard, category, scale, code, or search text
  • Rich Metadata - Includes code, name, description, colors, and more
  • Zero Dependencies - Lightweight and fast (runtime has no dependencies)
  • Tree-Shakeable - Only import what you need

Installation

npm install @odraw/symbols

Quick Start

import symbols from '@odraw/symbols';

// Get all symbols
const allSymbols = symbols.getAllSymbols();

// Get symbols by standard
const isomSymbols = symbols.getSymbolsByStandard('ISOM');

// Get symbols by category
const courseSymbols = symbols.getSymbolsByCategory('course');

// Get a specific symbol
const startSymbol = symbols.getSymbol('701', 'ISOM', 15000);

// Search symbols
const results = symbols.search('control');

Usage Examples

1. Load Symbols by Standard

import { getSymbolsByStandard, getAvailableStandards } from '@odraw/symbols';

// Get all available standards
const standards = getAvailableStandards();
// ['ISOM', 'ISSkiOM', 'ISMTBOM', 'ISSprOM', 'ISSOM', 'CourseDesign']

// Get ISOM symbols
const isomSymbols = getSymbolsByStandard('ISOM');

// Get ISSkiOM symbols
const skiSymbols = getSymbolsByStandard('ISSkiOM');

2. Browse Symbols by Category

import { getSymbolsGroupedByCategory, getAllCategories } from '@odraw/symbols';

// Get all categories with info
const categories = getAllCategories();
// Returns: [{ id, name, description, codeRange, color, icon }, ...]

// Get symbols grouped by category
const grouped = getSymbolsGroupedByCategory({ standard: 'ISOM', scale: 15000 });

grouped.forEach((symbols, category) => {
  console.log(`${category}: ${symbols.length} symbols`);
  symbols.forEach(symbol => {
    console.log(`  ${symbol.code} - ${symbol.name}`);
  });
});

3. Display Symbol Information

import { getSymbolsByCode } from '@odraw/symbols';

// Get all variations of symbol 701 (Start)
const startSymbols = getSymbolsByCode('701');

startSymbols.forEach(symbol => {
  console.log(`Code: ${symbol.code}`);
  console.log(`Name: ${symbol.name}`);
  console.log(`Description: ${symbol.description}`);
  console.log(`Standard: ${symbol.standard}`);
  console.log(`Scale: 1:${symbol.scale}`);
  console.log(`Category: ${symbol.category}`);
  console.log(`Color: ${symbol.color.hex}`);
  console.log(`SVG: ${symbol.svg ? 'Available' : 'Not available'}`);
});

4. Use SVG Symbols

import { getSymbol } from '@odraw/symbols';

// Get a symbol with SVG geometry
const controlSymbol = getSymbol('702', 'CourseDesign', 10000);

if (controlSymbol?.svg) {
  // Use the SVG directly in your HTML
  document.getElementById('symbol-container').innerHTML = controlSymbol.svg;
  
  // Or create an image element
  const img = document.createElement('img');
  img.src = `data:image/svg+xml;base64,${btoa(controlSymbol.svg)}`;
  
  // SVG includes metadata as data attributes
  console.log('Symbol metadata embedded in SVG');
}

// Load individual SVG files (if exported)
const svgUrl = `./symbols/svg/CourseDesign_10000_702.svg`;
const svgContent = await fetch(svgUrl).then(r => r.text());

5. Filter Symbols

import { filterSymbols } from '@odraw/symbols';

// Complex filtering
const filtered = filterSymbols({
  standard: ['ISOM', 'ISSprOM'],
  category: ['course', 'landforms'],
  scale: [15000, 10000],
  search: 'control'
});

// Filter by code prefix
const landformSymbols = filterSymbols({
  standard: 'ISOM',
  code: ['101', '102', '103', '104', '105']
});

6. Build a Symbol Picker

import { 
  getSymbolsGroupedByCategory, 
  getCategoryInfo,
  type Symbol 
} from '@odraw/symbols';

function SymbolPicker({ standard = 'ISOM', scale = 15000 }) {
  const grouped = getSymbolsGroupedByCategory({ standard, scale });
  
  return (
    <div className="symbol-picker">
      {Array.from(grouped.entries()).map(([category, symbols]) => {
        const info = getCategoryInfo(category);
        
        return (
          <div key={category} className="category">
            <h3 style={{ color: info.color }}>
              {info.icon} {info.name}
            </h3>
            <div className="symbols">
              {symbols.map(symbol => (
                <div 
                  key={symbol.id}
                  className="symbol"
                  title={`${symbol.code}: ${symbol.name}\n${symbol.description}`}
                  onClick={() => onSymbolSelect(symbol)}
                >
                  <div className="icon">
                    {symbol.svg ? (
                      <div 
                        dangerouslySetInnerHTML={{ __html: symbol.svg }}
                        style={{ width: '24px', height: '24px' }}
                      />
                    ) : (
                      <div 
                        className="placeholder"
                        style={{ backgroundColor: symbol.color.hex }}
                      >
                        {symbol.code}
                      </div>
                    )}
                  </div>
                  <span>{symbol.name}</span>
                </div>
              ))}
            </div>
          </div>
        );
      })}
    </div>
  );
}

7. Search Functionality

import { search } from '@odraw/symbols';

// Search in name, description, and code
const results = search('boulder');

results.forEach(symbol => {
  console.log(`${symbol.code} - ${symbol.name} (${symbol.standard})`);
});

8. Get Statistics

import { getStatistics } from '@odraw/symbols';

const stats = getStatistics();

console.log(`Total Symbols: ${stats.totalSymbols}`);
console.log(`Symbol Sets: ${stats.totalSymbolSets}`);
console.log(`Standards: ${stats.standards.join(', ')}`);
console.log(`Scales: ${stats.scales.map(s => `1:${s}`).join(', ')}`);

stats.categories.forEach(cat => {
  console.log(`${cat.name}: ${cat.count} symbols`);
});

API Reference

Main Functions

  • getAllSymbols() - Get all symbols
  • getSymbolById(id) - Get symbol by unique ID
  • getSymbolsByCode(code) - Get all symbols with a specific code
  • getSymbol(code, standard, scale) - Get a specific symbol
  • filterSymbols(filter) - Filter symbols by criteria
  • getSymbolsByStandard(standard) - Get symbols by standard
  • getSymbolsByCategory(category) - Get symbols by category
  • getSymbolsByScale(scale) - Get symbols by scale
  • getSymbolsGroupedByCategory(filter?) - Get symbols grouped by category
  • getSymbolsGroupedByCodePrefix(filter?) - Get symbols grouped by code prefix
  • search(query) - Search symbols
  • getStatistics() - Get library statistics

Types

type SymbolStandard = 'ISOM' | 'ISSkiOM' | 'ISMTBOM' | 'ISSprOM' | 'ISSOM' | 'CourseDesign';

type SymbolCategory = 
  | 'landforms'
  | 'rock-boulders'
  | 'water'
  | 'vegetation-white'
  | 'vegetation-green'
  | 'vegetation-boundaries'
  | 'man-made'
  | 'technical'
  | 'course';

interface Symbol {
  id: string;
  code: string;
  name: string;
  description: string;
  standard: SymbolStandard;
  category: SymbolCategory;
  type: 'point' | 'line' | 'area' | 'text' | 'combined';
  color: MapColor;
  scale: number;
  // ... more properties
}

Symbol Categories

| Category | Code Range | Description | Color | |----------|------------|-------------|-------| | Landforms | 101-117 | Contours, cliffs, earth banks | Brown | | Rock & Boulders | 201-213 | Cliffs, boulders, rocky areas | Black | | Water | 301-320 | Lakes, streams, marshes | Blue | | Vegetation (Open) | 401-419 | Open land, cultivation | Yellow | | Vegetation (Forest) | 501-524 | Forest, undergrowth | Green | | Vegetation Boundaries | 525-529 | Vegetation edges | Dark Green | | Man-made | 501-529 | Roads, buildings, fences | Black | | Technical | 801-899 | North lines, scales | Gray | | Course | 701-799 | Start, controls, finish | Purple |

Supported Standards

  • ISOM 2017-2 - International Specification for Orienteering Maps
  • ISSkiOM 2019 - International Specification for Ski Orienteering Maps
  • ISMTBOM - International Specification for Mountain Bike Orienteering Maps
  • ISSprOM 2019 - International Specification for Sprint Orienteering Maps
  • ISSOM - International Specification for Sport Orienteering Maps
  • Course Design - IOF Course Setting symbols

Supported Scales

  • 1:4000
  • 1:5000
  • 1:7500
  • 1:10000
  • 1:12500
  • 1:15000
  • 1:20000

SVG Rendering Status

The library extracts actual symbol geometry from .omap XML files and converts them to SVG format.

Currently Supported

  • ✅ Point symbols (circles, basic shapes)
  • ✅ Line symbols with proper colors and widths
  • ✅ Area symbols with fills
  • ✅ Text symbols with icon text
  • ✅ Basic coordinate parsing and scaling
  • ✅ Color extraction from .omap definitions

Complex Features (Simplified)

  • ⚠️ Multi-element symbols with start/mid/end patterns
  • ⚠️ Nested symbol definitions
  • ⚠️ Symbol patterns and advanced fills
  • ⚠️ Rotatable symbols with proper orientation
  • ⚠️ Dash patterns and line decorations
  • ⚠️ Curved paths and bezier curves

Recommendations

  • For most use cases: The automated SVG extraction works well
  • For critical symbols: Consider manually exporting from OpenOrienteering Mapper
  • For production: Use the hybrid approach (automated + manual for key symbols)

SVG Symbol Extraction

The library now automatically extracts SVG geometry from .omap files and exports individual SVG files for each symbol. This provides actual symbol renderings instead of placeholder icons.

Automated SVG Export

Export all 3,016+ symbols as individual SVG files:

# Export all symbols to SVG files
npm run export:svg

# This creates files like:
# symbols/svg/ISOM_15000_101.svg
# symbols/svg/CourseDesign_10000_702.svg
# etc.

Each SVG file includes:

  • Actual symbol geometry extracted from .omap files
  • Complete metadata as data attributes
  • Accessibility features (title, description)
  • Proper scaling and viewBox

SVG Export Options

Option 1: Automated Export (Current)

  • ✅ Fast - exports all symbols in seconds
  • ✅ Includes complete metadata
  • ✅ Reproducible and automated
  • ⚠️ Simplified rendering for complex symbols

Option 2: Manual Export from OpenOrienteering Mapper

  • ✅ Most accurate rendering
  • ✅ Handles all symbol complexities
  • ❌ Very time-consuming (3,016+ symbols)
  • ❌ Manual process

Option 3: Hybrid Approach (Recommended)

  • Use automated export for all symbols
  • Manually export critical symbols from Mapper
  • Replace auto-generated with manual for important symbols

Using Exported SVGs

// SVG files include metadata
const svgContent = await fetch('./symbols/svg/ISOM_15000_101.svg').then(r => r.text());

// Metadata is embedded in the SVG element:
// <svg data-code="101" data-name="Contour" data-standard="ISOM" ...>

Development

# Install dependencies
npm install

# Parse symbol files and extract SVG
npm run build:symbols

# Export symbols as individual SVG files
npm run export:svg

# Build library
npm run build

# Run tests
npm test

# Development mode
npm run dev

SVG Export Scripts

The library includes several scripts for working with SVG symbols:

  • scripts/export-symbols-svg.ts - Automated SVG export from .omap files
  • scripts/export-svg-guide.md - Guide for different SVG export approaches
  • scripts/mapper-export-guide.md - Manual export using OpenOrienteering Mapper

For detailed information about SVG extraction methods, see the guides in the scripts/ directory.

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Credits

Symbol definitions are based on the International Orienteering Federation (IOF) specifications and OpenOrienteering Mapper project.