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

egyptianbelts

v1.0.0

Published

Coordinate conversion and geospatial utilities supporting Egyptian Survey Belts, Egyptian National Coordinate systems, UTM, WGS84, DMS, DMM, and Easting/Northing transformations.

Readme

egyptianbelts

Coordinate conversion and geospatial utilities for Egyptian Survey Belts, Egyptian National Coordinate systems, UTM, WGS84, and DMS/DMM transformations. Built on top of proj4.

  • Convert GPS coordinates (Lat/Long) to Egyptian Belt coordinates (East/North) and back
  • Detect which Egyptian survey belt a coordinate falls in
  • Convert between UTM and decimal degrees
  • Convert between Decimal Degrees, DMS (Degrees/Minutes/Seconds), and DMM (Degrees/Decimal Minutes)

Compatibility

| Environment | Supported | |---|---| | Node.js | ✅ Yes (CommonJS, require) | | Bundlers (Vite, Webpack, etc.) | ✅ Yes | | TypeScript | ✅ Yes — ships with its own index.d.ts type declarations, no @types package needed | | Browser (via bundler) | ✅ Yes | | React / React Native | ✅ Yes — just remember values returned are plain objects, not renderable on their own (see note at the bottom) | | Dependencies | Requires proj4 (installed automatically) |


Installation

npm install egyptianbelts

Import

// CommonJS
const { decimalToEgyptianBelt } = require("egyptianbelts");

// ES Modules / TypeScript
import { decimalToEgyptianBelt } from "egyptianbelts";

Table of Contents

  1. Belts covered
  2. Types Reference
  3. getBeltName
  4. detectBelt
  5. getEPSGForBelt
  6. nearestBelt
  7. dmsToDecimal
  8. dmmToDecimal
  9. decimalToEgyptianBelt
  10. egyptianBeltToDecimal
  11. getUtmZoneDesignation
  12. decimalToUTM
  13. utmToDecimal
  14. Using results in React

Belts covered

Egypt is divided into 5 survey belts, each with its own official EPSG projection code, used internally by the belt-conversion functions below:

| Belt key | Friendly name | EPSG code | |---|---|---| | RedBelt | Red Belt | EPSG:22992 | | BlueBelt | Blue Belt | EPSG:22991 | | PurpleBelt | Purple Belt | EPSG:22994 | | SouthernRedBelt | Southern Red Belt | EPSG:22999 | | SouthernPurpleBelt | Southern Purple Belt | EPSG:22995 |


Types Reference

These are the TypeScript shapes returned by the functions below. If you're using plain JavaScript you can ignore this section — it's just here so you know what fields to expect on the returned objects.

interface EgyptianBeltResult {
  East: number;
  North: number;
  Belt: string;
  EPSG: string | null;
}

interface EgyptianBeltToDecimalResult {
  Lat: number | null;
  Long: number | null;
  Belt: string | null;
  EPSG: string | null;
}

interface UTMResult {
  zone: string;
  easting: number;
  northing: number;
}

interface UTMToDecimalResult {
  Lat: number | null;
  Long: number | null;
  zoneLetter: string | null;
}

getBeltName

In simple words: turns a belt's internal code name (like "RedBelt") into a nice human-readable label (like "Red Belt").

function getBeltName(beltName: string): string | null;

Parameters

| Name | Type | Description | |---|---|---| | beltName | string | One of: "RedBelt", "BlueBelt", "PurpleBelt", "SouthernRedBelt", "SouthernPurpleBelt" |

Returns: string | null — the friendly name, or null if the belt name isn't recognized.

Example

getBeltName("RedBelt");
// "Red Belt"

getBeltName("NotABelt");
// null

detectBelt

In simple words: give it a GPS point (latitude, longitude) and it tells you which official Egyptian belt that point falls inside.

function detectBelt(lat: number, lon: number): string | null;

Parameters

| Name | Type | Description | |---|---|---| | lat | number | Latitude in decimal degrees | | lon | number | Longitude in decimal degrees |

Returns: string | null — the belt key (e.g. "RedBelt"), or null if the point doesn't fall inside any belt boundary.

Example

detectBelt(30, 31);
// "RedBelt"

detectBelt(0, 0);
// null  (outside all Egyptian belts)

💡 If you need a result even for points outside all belts, use nearestBelt instead.


getEPSGForBelt

In simple words: looks up the official EPSG projection code for a given belt. If you don't give it a belt, it defaults to the Red Belt's code.

function getEPSGForBelt(beltName?: string | null): string;

Parameters

| Name | Type | Description | |---|---|---| | beltName | string \| null (optional) | The belt key. If omitted or null, defaults to RedBelt's EPSG code. |

Returns: string — an EPSG code such as "EPSG:22992".

Example

getEPSGForBelt("BlueBelt");
// "EPSG:22991"

getEPSGForBelt();
// "EPSG:22992"  (default: Red Belt)

nearestBelt

In simple words: like detectBelt, but never gives up — even if your point is outside every belt, it finds the closest one.

function nearestBelt(lat: number, lon: number): string;

Parameters

| Name | Type | Description | |---|---|---| | lat | number | Latitude in decimal degrees | | lon | number | Longitude in decimal degrees |

Returns: string — the belt key of the closest belt. Always returns a value (never null).

Example

nearestBelt(0, 0);
// "SouthernPurpleBelt" (whichever is geographically closest)

dmsToDecimal

In simple words: converts a coordinate written the "old-fashioned" way — degrees, minutes, seconds (like 30° 15' 20") — into a single decimal number (like 30.2556).

function dmsToDecimal(d: number, m: number, s: number): number;

Parameters

| Name | Type | Description | |---|---|---| | d | number | Degrees | | m | number | Minutes | | s | number | Seconds |

Returns: number — the decimal degree value. The sign of d determines the sign of the result (so use a negative d for South/West coordinates).

Example

dmsToDecimal(30, 15, 20);
// 30.255555...

dmsToDecimal(-30, 15, 20);
// -30.255555...

dmmToDecimal

In simple words: same idea as above, but for coordinates written as degrees + decimal minutes (like 30° 15.33'), a format common on GPS devices.

function dmmToDecimal(d: number, m: number): number;

Parameters

| Name | Type | Description | |---|---|---| | d | number | Degrees | | m | number | Decimal minutes |

Returns: number — the decimal degree value.

Example

dmmToDecimal(30, 15.333);
// 30.25555

decimalToEgyptianBelt

In simple words: the main "GPS → Egyptian survey coordinates" converter. Give it a latitude/longitude, and it automatically figures out which belt the point is in, then converts it into that belt's East/North coordinate system.

function decimalToEgyptianBelt(lat: number, lon: number): EgyptianBeltResult;

Parameters

| Name | Type | Description | |---|---|---| | lat | number | Latitude in decimal degrees | | lon | number | Longitude in decimal degrees |

Returns: EgyptianBeltResult

| Field | Type | Description | |---|---|---| | East | number | Easting value in the detected belt's coordinate system | | North | number | Northing value in the detected belt's coordinate system | | Belt | string | Friendly belt name (e.g. "Red Belt"), or "Unkown" if no belt matched | | EPSG | string \| null | The EPSG code used for the conversion, or null if no belt matched |

Example

decimalToEgyptianBelt(30, 31);
// {
//   East: 620435.123456,
//   North: 815234.654321,
//   Belt: "Red Belt",
//   EPSG: "EPSG:22992"
// }

⚠️ If the point doesn't fall inside any belt, East and North will be NaN, Belt will be the string "Unkown" (note: this is a known typo in the current package version, not "Unknown"), and EPSG will be null. Always check EPSG !== null before trusting the result.


egyptianBeltToDecimal

In simple words: the reverse of the function above — give it Egyptian East/North coordinates plus the belt they belong to, and it converts them back into GPS latitude/longitude.

function egyptianBeltToDecimal(
  east: number,
  north: number,
  belt: string
): EgyptianBeltToDecimalResult;

Parameters

| Name | Type | Description | |---|---|---| | east | number | Easting value | | north | number | Northing value | | belt | string | The belt key the coordinates belong to, e.g. "RedBelt" |

Returns: EgyptianBeltToDecimalResult

| Field | Type | Description | |---|---|---| | Lat | number \| null | Latitude in decimal degrees, or null if the belt is invalid | | Long | number \| null | Longitude in decimal degrees, or null if the belt is invalid | | Belt | string \| null | The belt key you passed in, echoed back | | EPSG | string \| null | The EPSG code used |

Example

egyptianBeltToDecimal(620435.12, 815234.65, "RedBelt");
// { Lat: 30.000012, Long: 31.000004, Belt: "RedBelt", EPSG: "EPSG:22992" }

egyptianBeltToDecimal(1000, 1000, "NotABelt");
// { Lat: null, Long: null, Belt: null, EPSG: null }

⚠️ You must pass the exact belt key ("RedBelt", "BlueBelt", etc.), not the friendly name ("Red Belt"). Passing an unrecognized belt returns all null values.


getUtmZoneDesignation

In simple words: figures out which UTM zone (a worldwide grid system used in mapping) a GPS coordinate belongs to.

function getUtmZoneDesignation(latitude: number, longitude: number): string;

Parameters

| Name | Type | Description | |---|---|---| | latitude | number | Latitude in decimal degrees | | longitude | number | Longitude in decimal degrees |

Returns: string — the UTM zone number plus hemisphere letter, e.g. "36 N".

Example

getUtmZoneDesignation(30, 31);
// "36 N"

getUtmZoneDesignation(-30, 31);
// "36 S"

decimalToUTM

In simple words: converts a GPS latitude/longitude into UTM Easting/Northing coordinates.

function decimalToUTM(
  latitude: number,
  longitude: number,
  zoneLetter: string
): UTMResult;

Parameters

| Name | Type | Description | |---|---|---| | latitude | number | Latitude in decimal degrees | | longitude | number | Longitude in decimal degrees | | zoneLetter | string | Hemisphere letter to force, e.g. "N" or "S". If you pass an empty string, it's auto-detected from the coordinates. |

Returns: UTMResult

| Field | Type | Description | |---|---|---| | zone | string | UTM zone number + letter, e.g. "36N" | | easting | number | UTM easting | | northing | number | UTM northing |

Example

decimalToUTM(30, 31, "N");
// { zone: "36N", easting: 500123.45, northing: 3320456.78 }

utmToDecimal

In simple words: the reverse of the above — converts UTM Easting/Northing coordinates back to GPS latitude/longitude.

function utmToDecimal(
  easting: number,
  northing: number,
  zoneDesignation: string
): UTMToDecimalResult;

Parameters

| Name | Type | Description | |---|---|---| | easting | number | UTM easting | | northing | number | UTM northing | | zoneDesignation | string | Zone number + letter combined, e.g. "36N" |

Returns: UTMToDecimalResult

| Field | Type | Description | |---|---|---| | Lat | number \| null | Latitude in decimal degrees, or null on failure / out-of-range result | | Long | number \| null | Longitude in decimal degrees, or null on failure / out-of-range result | | zoneLetter | string \| null | The zone letter you passed in, echoed back, or null on failure |

Example

utmToDecimal(500123.45, 3320456.78, "36N");
// { Lat: 30.000012, Long: 31.000005, zoneLetter: "N" }

⚠️ Known quirk: in the current version, decimalToUTM and utmToDecimal interpret the north/south hemisphere flag inconsistently with each other (their internal isSouthernHemisphere / isNorthern checks use different comparisons). For most locations in Egypt (northern hemisphere) results are correct, but if you're working near zone boundaries or in the southern hemisphere, double-check your output against a trusted source.


Using results in React

Every conversion function returns a plain object, not text — so you can't drop the result directly into JSX. Access its fields instead:

import { decimalToEgyptianBelt } from "egyptianbelts";

function App() {
  const result = decimalToEgyptianBelt(30, 31);

  return (
    <div>
      <p>East: {result.East}</p>
      <p>North: {result.North}</p>
      <p>Belt: {result.Belt}</p>
      <p>EPSG: {result.EPSG ?? "N/A"}</p>
    </div>
  );
}

Or, for quick debugging, stringify the whole object:

<pre>{JSON.stringify(result, null, 2)}</pre>

License

MIT © Mohamed Karbawy