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 🙏

© 2024 – Pkg Stats / Ryan Hefner

universal-geocoder

v0.14.2

Published

Universal geocoding abstraction server-side and client-side with multiple built-in providers

Downloads

441

Readme

Universal Geocoder Logo

Universal Geocoder

CI codecov

npm downloads

dependency-count minified-size tree-shaking types

Universal Geocoder is a universal JavaScript library for server-side and client-side geocoding applications with multiple built-in providers.

Need geocoding 🌍️ in your website or application? Don't want to be vendor-locked to a service? ✨️ Universal Geocoder ✨️ is for you!

Depending of the chosen provider, it can use geocoding, reverse geocoding or IP geolocation.

Universal Geocoder is a TypeScript fork of GeocoderJS, itself a port of the Geocoder PHP library.

This library is platform agnostic: it is available either server-side (Node) or client-side (browsers, React Native, Electron).

It aims to be compatible with a maximum of browsers (even old ones) and provides multiple ways to use it, from an old use (available in global environment, results from callbacks) to the most modern use (available as a module, async / await results).

Installation

Add the library to your project:

npm install --save universal-geocoder

⚠️ Warning: If you need to use this library in an environment not supporting the Promise API such as Internet Explorer, you must install an ES6 Promise compatible polyfill like es6-promise.

Usage

You can either use Universal Geocoder as a module (both CommonJS and ES module syntaxes are provided) or as a direct dependency.

As a module:

import UniversalGeocoder from "universal-geocoder";

const openStreetMapGeocoder = UniversalGeocoder.createGeocoder("openstreetmap");

// async / await syntax
(async () =>
  console.log(await openStreetMapGeocoder.geocode("1600 Pennsylvania Ave NW, Washington, DC"))
)();

// callback syntax
openStreetMapGeocoder.geocode("1600 Pennsylvania Ave NW, Washington, DC", (result) => {
  console.log(result);
});

For this example, the output will be something like this:

[
  NominatimGeocoded {
    coordinates: { latitude: 38.8976998, longitude: -77.03655348862276 },
    bounds: {
      latitudeSW: 38.8974898,
      longitudeSW: -77.0368542,
      latitudeNE: 38.897911,
      longitudeNE: -77.0362526
    },
    formattedAddress: undefined,
    streetNumber: '1600',
    streetName: 'Pennsylvania Avenue Northwest',
    subLocality: undefined,
    locality: 'Washington',
    postalCode: '20500',
    region: 'District of Columbia',
    adminLevels: [
      AdminLevel {
        level: 1,
        name: 'District of Columbia',
        code: undefined
      },
      AdminLevel {
        level: 2,
        name: 'Washington',
        code: undefined
      }
    ],
    country: 'United States of America',
    countryCode: 'us',
    timezone: undefined,
    displayName: 'White House, 1600, Pennsylvania Avenue Northwest, Washington, District of Columbia, 20500, United States of America',
    osmId: 238241022,
    osmType: 'way',
    category: 'historic',
    type: 'castle',
    attribution: 'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright'
  },
  // ... (other results)
]

If you want to use the library as a direct dependecy (for browsers only), copy dist/universal-geocoder.js or dist/universal-geocoder.min.js to your dependencies.

Universal Geocoder will be available in the global environment:

const openStreetMapGeocoder = UniversalGeocoder.createGeocoder("openstreetmap");

openStreetMapGeocoder.geodecode("44.915", "-93.21", (result) => {
  console.log(result);
});

For a more advanced usage, see the example below:

import UniversalGeocoder, { ReverseQuery } from "universal-geocoder";

const googleGeocoder = UniversalGeocoder.createGeocoder({
  provider: "googlemaps",
  apiKey: "YOUR_API_KEY",
  useSsl: true,
  useJsonp: false,
  // other specific provider options
});

(async () =>
  console.log(await googleGeocoder.geocode({
    text: "1600 Pennsylvania Ave, Washington, DC",
    locale: "FR",
    limit: 10,
    // other specific provider parameters
  }))
)();

const reverseQuery = ReverseQuery.create({
  coordinates: {
    latitude: "44.915",
    longitude: "-93.21",
  },
})
.withLocale("FR")
.withLimit(7);
(async () =>
  console.log(await googleGeocoder.geodecode(reverseQuery))
)();

Common Options (createGeocoder method)

  • useSsl: boolean to use the HTTPS API of the providers
  • useJsonp: boolean to use JSONP
  • apiKey: the API key to use for the provider

Common geocode parameters (GeocodeQuery object)

  • text: what is searched
  • ip: the IP searched
  • bounds (object with latitudeSW, longitudeSW, latitudeNE and longitudeNE keys): the bounds to use (either bias or filter the results)
  • locale: the locale to use for the query
  • limit: the maximum number of results to have

Common geodecode parameters (ReverseQuery object)

  • coordinates (object with latitude, longitude keys): the coordinates to search for
  • locale: the locale to use for the query
  • limit: the maximum number of results to have

Common Result Properties (Geocoded object)

The result of a query is a Geocoded object which maps the following common information:

  • Coordinates (object with latitute and longitude keys)
  • Bounds (object with latitudeSW, longitudeSW, latitudeNE, longitudeNE keys)
  • Formatted address
  • Address details: street number, street name, (sub) locality, postal code, region, administration levels, country (with its code)
  • Time zone

You can either use getter methods to retrieve them or use the toObject method to manipulate an object containing the properties.

Providers

Universal Geocoder comes with modules to integrate with various geocoding providers.

The following table summarizes the features of each:

Specific Provider Usage

The documentation for specific provider options, parameters and results can be found here.

Special Providers

A chain provider is available: it iterates over multiple providers.

For more information, see its documentation.

Dumpers

Dumpers transform a Geocoded object to another format.

GeoJSON

GeoJSON is a format for encoding a variety of geographic data structures.

Usage

import UniversalGeocoder, { GeoJsonDumper } from "universal-geocoder";

const nominatimGeocoder = UniversalGeocoder.createGeocoder("nominatim");

(async () => {
  const result = await nominatimGeocoder.geocode("1600 Pennsylvania Ave NW, Washington, DC");
  console.log(result);
  console.log("GeoJSON:", GeoJsonDumper.dump(result[0]));
})();

Building

npm run build

Testing

Unit and functional tests are handled by Jasmine. To run tests from the command line, use:

npm test

If you need to record new API calls, use:

npm run test-record

You can also check if the examples are running correctly.

For the Web:

npm run serve

Then go to http://localhost:8080/example/web, choose a provider and open the console.

For Node:

npm run ts-node -- example/node/provider.ts

FAQ

Q: When using Universal Geocoder client-side, how to make sure the API key is not stolen?

A: First of all, there are some providers that do not use an API key, like OpenStreetMap (Nominatim) or GeoPlugin.

If you want to use a provider with an API key, the best approach is generally to use Universal Geocoder in the server-side (Node) and to call it from the client-side. This way the API key is not exposed directly.

Some providers allow to add URL restrictions when generating a token, like Mapbox. Even if the token is visible, it mitigates its unwanted use since the Origin header cannot be changed in a browser environment. However, the stolen token would be still usable in a server environment (for instance with cURL).