country-coder
๐ โก๏ธ ๐ฉ๐ฐ Convert longitude-latitude pairs to ISO 3166-1 codes quickly and locally
What is it?
country-coder is a lightweight package that looks up region identifiers for geographic points without calling a server. It can code and convert between several common IDs:
Results can optionally include non-country ISO 3166-1 features, such as Puerto Rico (PR) or the Isle of Man (IM). Some unofficial yet exceptionally-reserved or user-assigned ISO codes are also supported, such as the European Union (EU) and Kosovo (XK), as well as M49 regions like Africa (002) or Polynesia (061).
In addition to identifiers, country-coder can provide basic regional information:
Advantages
Client-side coding has a number of benefits over server-side solutions:
- โ
๐
Performance: get fast, reliable results at scale
- โ
โ๏ธ Ease of Use: forget async callbacks, network errors, API keys, and rate limits
- โ
๐ถ Privacy: keep your location data on-device
- โ
๐ด Offline Workflows: deploy to connection-challenged environments
Caveats
country-coder prioritizes package size and lookup speed over precision. Thus, it's not suitable for some situations and use cases:
- ๐ซ ๐ Disputed Borders: only one country is coded per point, roughly the "de facto controlling country"
- ๐ซ ๐ข Maritime Borders: only points on land are supported; borders over water are highly generalized
- ๐ซ ๐ Complex Borders: land borders are of varying detail and may be imprecise at granular scales
- ๐ซ ๐งฉ Country Subdivisions: provinces and similar features under ISO 3166-2 cannot be coded
- ๐ซ ๐ Multilingual Naming: only basic English names are included; get display names via another package or the Wikidata API
- ๐ซ ๐ Spatial Operations: a feature's calculated area, bounding box, etc. will likely be inaccurate
- ๐ซ ๐บ Mapmaking: the border data is not intended for rendering
Installing
npm install country-coder
This library is available in both ES5/CommonJS and ES6 module formats.
const countryCoder = require('country-coder');
const iso1A2Code = require('country-coder').iso1A2Code;
import * as countryCoder from 'country-coder';
import { iso1A2Code } from 'country-coder';
Quick Start
Simply pass in a [longitude, latitude] to iso1A2Code to get the country code.
iso1A2Code([-4.5, 54.2]);
To include non-country territories, pass in territory for the level option.
iso1A2Code([-4.5, 54.2], { level: 'territory' });
The same method can convert from other identifiers.
iso1A2Code('Q145');
Read the full API reference to see everything country-coder can do.
Contributing
This package is kept intentionally minimal. However, if you find a bug or have an interesting idea for an enhancement, feel free to open an Issue and/or Pull Request.
API Reference
Methods
- feature(query: Location | string | number, opts?: CodingOptions): RegionFeature?
- iso1A2Code(query: Location | string | number, opts?: CodingOptions): string?
- iso1A3Code(query: Location | string | number, opts?: CodingOptions): string?
- iso1N3Code(query: Location | string | number, opts?: CodingOptions): string?
- m49Code(query: Location | string | number, opts?: CodingOptions): string?
- wikidataQID(query: Location | string | number, opts?: CodingOptions): string?
- emojiFlag(query: Location | string | number, opts?: CodingOptions): string?
- featuresContaining(query: Location | string | number): [RegionFeature]
- featuresIn(id: string | number): [RegionFeature]
- aggregateFeature(id: string | number): [RegionFeature]
- isIn(query: Location | string | number, bounds: string | number): boolean
- isInEuropeanUnion(query: Location | string | number): boolean
- driveSide(query: Location | string | number): string?
- roadSpeedUnit(query: Location | string | number): string?
- callingCodes(query: Location | string | number): [string]
Properties
- borders: RegionFeatureCollection - the base GeoJSON containing all features
Types
Methods
# feature(query: Location | string | number, opts?: CodingOptions): RegionFeature?
<>
Returns the GeoJSON feature from borders for the given location or identifier and options, if found. Note that the geometry of the feature may not contain its full bounds (see aggregateFeature).
feature([-4.5, 54.2]);
feature([-4.5, 54.2], { level: 'territory' });
feature([0, 90]);
feature('GB');
feature('GBR');
feature('826');
feature(826);
feature('Q145');
feature('๐ฌ๐ง');
feature('UK');
feature('IM');
feature('United Kingdom');
let pointGeoJSON = { type: 'Feature', geometry: { type: 'Point', coordinates: [-4.5, 54.2] } };
feature(pointGeoJSON);
feature(pointGeoJSON.geometry);
# iso1A2Code(query: Location | string | number, opts?: CodingOptions): string?
<>
Returns the ISO 3166-1 alpha-2 code for the given location or identifier and options, if found.
iso1A2Code([-4.5, 54.2]);
iso1A2Code([-4.5, 54.2], { level: 'territory' });
iso1A2Code([0, 90]);
iso1A2Code('GBR');
iso1A2Code('826');
iso1A2Code(826);
iso1A2Code('Q145');
iso1A2Code('๐ฌ๐ง');
iso1A2Code('UK');
iso1A2Code('IMN');
iso1A2Code('United Kingdom');
let pointGeoJSON = { type: 'Feature', geometry: { type: 'Point', coordinates: [-4.5, 54.2] } };
iso1A2Code(pointGeoJSON);
iso1A2Code(pointGeoJSON.geometry);
# iso1A3Code(query: Location | string | number, opts?: CodingOptions): string?
<>
Returns the ISO 3166-1 alpha-3 code for the given location or identifier and options, if found.
iso1A3Code([-4.5, 54.2]);
iso1A3Code([-4.5, 54.2], { level: 'territory' });
iso1A3Code([0, 90]);
iso1A3Code('GB');
iso1A3Code('826');
iso1A3Code(826);
iso1A3Code('Q145');
iso1A3Code('๐ฌ๐ง');
iso1A3Code('UK');
iso1A3Code('IM');
iso1A3Code('United Kingdom');
let pointGeoJSON = { type: 'Feature', geometry: { type: 'Point', coordinates: [-4.5, 54.2] } };
iso1A3Code(pointGeoJSON);
iso1A3Code(pointGeoJSON.geometry);
# iso1N3Code(query: Location | string | number, opts?: CodingOptions): string?
<>
Returns the ISO 3166-1 numeric-3 code for the given location or identifier and options, if found. For more comprehensive coverage, see m49Code.
iso1N3Code([-4.5, 54.2]);
iso1N3Code([-4.5, 54.2], { level: 'territory' });
iso1N3Code([0, 90]);
iso1N3Code('GB');
iso1N3Code('GBR');
iso1N3Code('Q145');
iso1N3Code('๐ฌ๐ง');
iso1N3Code('UK');
iso1N3Code('IM');
iso1N3Code('Q15');
iso1A3Code('United Kingdom');
let pointGeoJSON = { type: 'Feature', geometry: { type: 'Point', coordinates: [-4.5, 54.2] } };
iso1N3Code(pointGeoJSON);
iso1N3Code(pointGeoJSON.geometry);
# m49Code(query: Location | string | number, opts?: CodingOptions): string?
<>
Returns the United Nations M49 code for the given location or identifier and options, if found. These codes are a superset of ISO 3166-1 numeric-3 codes, adding a subdivision (Sark) and transnational regions (e.g. Asia, Central America, Polynesia).
m49Code([-4.5, 54.2]);
m49Code([-4.5, 54.2], { level: 'territory' });
m49Code([0, 90]);
m49Code('GB');
m49Code('GBR');
m49Code('Q145');
m49Code('๐ฌ๐ง');
m49Code('UK');
m49Code('IM');
m49Code('Q15');
m49Code('United Kingdom');
let pointGeoJSON = { type: 'Feature', geometry: { type: 'Point', coordinates: [-4.5, 54.2] } };
m49Code(pointGeoJSON);
m49Code(pointGeoJSON.geometry);
# wikidataQID(query: Location | string | number, opts?: CodingOptions): string?
<>
Returns the Wikidata QID for the given location or identifier and options, if found.
wikidataQID([-4.5, 54.2]);
wikidataQID([-4.5, 54.2], { level: 'territory' });
wikidataQID([0, 90]);
wikidataQID('GB');
wikidataQID('GBR');
wikidataQID('826');
wikidataQID(826);
wikidataQID('๐ฌ๐ง');
wikidataQID('UK');
wikidataQID('IM');
wikidataQID('United Kingdom');
let pointGeoJSON = { type: 'Feature', geometry: { type: 'Point', coordinates: [-4.5, 54.2] } };
wikidataQID(pointGeoJSON);
wikidataQID(pointGeoJSON.geometry);
# emojiFlag(query: Location | string | number, opts?: CodingOptions): string?
<>
Returns the emoji flag sequence for the given location or identifier and options, if found.
emojiFlag([-4.5, 54.2]);
emojiFlag([-4.5, 54.2], { level: 'territory' });
emojiFlag([0, 90]);
emojiFlag('GB');
emojiFlag('GBR');
emojiFlag('826');
emojiFlag(826);
emojiFlag('Q145');
emojiFlag('UK');
emojiFlag('IM');
emojiFlag('United Kingdom');
let pointGeoJSON = { type: 'Feature', geometry: { type: 'Point', coordinates: [-4.5, 54.2] } };
emojiFlag(pointGeoJSON);
emojiFlag(pointGeoJSON.geometry);
# featuresContaining(query: Location | string | number): [RegionFeature]
<>
Returns all the the features of any type that contain or match the given location or identifier, if any. If strict is true then only features that are strictly containing are returned.
featuresContaining([-4.5, 54.2]);
featuresContaining([0, 51.5]);
featuresContaining([6.1, 46.2]);
featuresContaining([0, 90]);
featuresContaining('GB');
featuresContaining('GBR');
featuresContaining('826');
featuresContaining(826);
featuresContaining('Q145');
featuresContaining('๐ฌ๐ง');
featuresContaining('UK');
featuresContaining('154');
featuresContaining('GB', true);
featuresContaining('154', true);
let pointGeoJSON = { type: 'Feature', geometry: { type: 'Point', coordinates: [0, -90] } };
featuresContaining(pointGeoJSON);
featuresContaining(pointGeoJSON.geometry);
# featuresIn(id: string | number): [RegionFeature]
<>
Returns all the the features that match or are contained within the given identifier, if any. If strict is true then only features that are strictly contained are returned.
featuresIn('CN');
featuresIn('CHN');
featuresIn('156');
featuresIn(156);
featuresIn('Q148');
featuresIn('๐จ๐ณ');
featuresIn('China');
featuresIn('CN', true);
# aggregateFeature(id: string | number): [RegionFeature]
<>
Returns a new feature with the properties of the feature matching id and the combined geometry of it and all its component features. This step is not necessary when only accessing a feature's properties.
aggregateFeature('CN');
aggregateFeature('CHN');
aggregateFeature('156');
aggregateFeature(156);
aggregateFeature('Q148');
aggregateFeature('๐จ๐ณ');
aggregateFeature('China');
# isIn(query: Location | string | number, bounds: string | number): boolean
<>
Returns true if the feature matching query is, or is within, the feature matching bounds.
isIn([0, 51.5], 'GB');
isIn([-4.5, 54.2], 'IM');
isIn([-4.5, 54.2], 'GB');
isIn([-4.5, 54.2], 'CH');
isIn([6.1, 46.2], 'GB');
isIn('IM', 'GB');
isIn('GB', 'IM');
isIn('GB', '150');
isIn('GBR', 150);
isIn('826', 'Q46');
isIn('๐ฎ๐ฒ', '๐ฌ๐ง');
isIn('United Kingdom', 'Europe');
isIn('United Kingdom', 'Africa');
let pointGeoJSON = { type: 'Feature', geometry: { type: 'Point', coordinates: [0, 51.5] } };
isIn(pointGeoJSON, 'GB');
isIn(pointGeoJSON.geometry, 'GB');
# isInEuropeanUnion(query: Location | string | number): boolean
<>
Returns true if the feature with the given location or identifier is found to be part of the European Union. This is a convenience method for isIn(query, 'EU').
isInEuropeanUnion([0, 51.5]);
isInEuropeanUnion([-4.5, 54.2]);
isInEuropeanUnion([6.1, 46.2]);
isInEuropeanUnion([0, 90]);
isInEuropeanUnion('EU');
isInEuropeanUnion('GB');
isInEuropeanUnion('GBR');
isInEuropeanUnion('826');
isInEuropeanUnion(826);
isInEuropeanUnion('Q145');
isInEuropeanUnion('๐ฌ๐ง');
isInEuropeanUnion('UK');
isInEuropeanUnion('United Kingdom');
isInEuropeanUnion('IM');
isInEuropeanUnion('CH');
let pointGeoJSON = { type: 'Feature', geometry: { type: 'Point', coordinates: [0, 51.5] } };
isInEuropeanUnion(pointGeoJSON);
isInEuropeanUnion(pointGeoJSON.geometry);
# driveSide(query: Location | string | number): string?
<>
Returns the side of the road on which traffic drives for the given location or identifier, if found.
driveSide([0, 51.5]);
driveSide([6.1, 46.2]);
driveSide([0, 90]);
driveSide('EU');
driveSide('GB');
driveSide('GBR');
driveSide('826');
driveSide(826);
driveSide('Q145');
driveSide('๐ฌ๐ง');
driveSide('UK');
driveSide('United Kingdom');
driveSide('CH');
let pointGeoJSON = { type: 'Feature', geometry: { type: 'Point', coordinates: [0, 51.5] } };
driveSide(pointGeoJSON);
driveSide(pointGeoJSON.geometry);
# roadSpeedUnit(query: Location | string | number): string?
<>
Returns the unit of speed used on traffic signs for the given location or identifier, if found.
roadSpeedUnit([0, 51.5]);
roadSpeedUnit([6.1, 46.2]);
roadSpeedUnit([0, 90]);
roadSpeedUnit('EU');
roadSpeedUnit('GB');
roadSpeedUnit('GBR');
roadSpeedUnit('826');
roadSpeedUnit(826);
roadSpeedUnit('Q145');
roadSpeedUnit('๐ฌ๐ง');
roadSpeedUnit('UK');
roadSpeedUnit('United Kingdom');
roadSpeedUnit('CH');
let pointGeoJSON = { type: 'Feature', geometry: { type: 'Point', coordinates: [0, 51.5] } };
roadSpeedUnit(pointGeoJSON);
roadSpeedUnit(pointGeoJSON.geometry);
# callingCodes(query: Location | string | number): [string]
<>
Returns the full international calling code prefix of phone numbers for the given location or identifier, if any. All prefixes have a country code, with some also including an area code separated by a space character. These are commonly formatted with a preceding plus sign (e.g. +1 242).
callingCodes([0, 51.5]);
callingCodes([0, 90]);
callingCodes('EU');
callingCodes('GB');
callingCodes('GBR');
callingCodes('826');
callingCodes(826);
callingCodes('Q145');
callingCodes('๐ฌ๐ง');
callingCodes('UK');
callingCodes('United Kingdom');
callingCodes('BS');
callingCodes('JA');
let pointGeoJSON = { type: 'Feature', geometry: { type: 'Point', coordinates: [0, 51.5] } };
callingCodes(pointGeoJSON);
callingCodes(pointGeoJSON.geometry);
Properties
# borders: RegionFeatureCollection
<>
The base GeoJSON feature collection used for feature lookup. While this property is public, modifying it is not recommended and may have unintended effects.
Types
# Vec2
An array of two numbers as [longitude, latitude] referenced to the WGS 84 datum.
[number, number]
# PointGeometry
GeoJSON Point geometry as specified by RFC 7946.
# PointFeature
A GeoJSON Feature with Point geometry as specified by RFC 7946.
# Location
A geographic location in one of the supported formats.
Vec2 | PointGeometry | PointFeature
# CodingOptions
An object containing options used for geocoding.
level: string, for overlapping features, the preferred geographic classification of the one to code. If no feature exists at the specified level, the feature at the next-highest level is coded, if any. The possible values map directly to the level property of RegionFeatureProperties objects.
union: European Union
region: Africa, Americas, Antarctica, Asia, Europe, Oceania
subregion: Sub-Saharan Africa, North America, Micronesia, etc.
intermediateRegion: Eastern Africa, South America, Channel Islands, etc.
country: Ethiopia, Brazil, United States, etc.
territory: Puerto Rico, Gurnsey, Hong Kong, etc.
subterritory: Sark, Ascension Island, Diego Garcia, etc.
# RegionFeature
A GeoJSON feature representing a codable geographic area.
# RegionFeatureProperties
An object containing the attributes of a RegionFeature object.
id: string, a unique ID for this feature specific to country-coder
iso1A2: string, ISO 3166-1 alpha-2 code
iso1A3: string, ISO 3166-1 alpha-3 code
iso1N3: string, ISO 3166-1 numeric-3 code
m49: string, UN M49 code
wikidata: string, Wikidata QID
emojiFlag: string, the emoji flag sequence derived from this feature's ISO 3166-1 alpha-2 code
nameEn: string, common name in English
aliases: [string], additional identifiers which can be used to look up this feature
country: string, for features entirely within a country, the ISO 3166-1 alpha-2 code for that country
groups: [string], the ISO 3166-1 alpha-2 or M49 codes of other features this feature is entirely within
members: [string], the ISO 3166-1 alpha-2 or M49 codes of other features this feature entirely contains, the inverse of groups
level: string, the rough geographic classification of this feature
union: European Union
region: Africa, Americas, Antarctica, Asia, Europe, Oceania
subregion: Sub-Saharan Africa, North America, Micronesia, etc.
intermediateRegion: Eastern Africa, South America, Channel Islands, etc.
country: Ethiopia, Brazil, United States, etc.
territory: Puerto Rico, Gurnsey, Hong Kong, etc.
subterritory: Sark, Ascension Island, Diego Garcia, etc.
isoStatus: string, the status of this feature's ISO 3166-1 code(s), if any
official: officially-assigned
excRes: exceptionally-reserved
usrAssn: user-assigned
driveSide: string, the side of the road on which traffic drives within this feature
roadSpeedUnit: string, the speed unit used on traffic signs in this feature
mph: miles per hour
km/h: kilometers per hour
callingCodes: [string], the international calling codes for this feature, sometimes including area codes
# RegionFeatureCollection
A GeoJSON feature collection containing RegionFeature objects.