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

@goparrot/geocoder

v4.5.0

Published

TypeScript GeoCoder, node geocoding library, supports google maps, mapquest, here, open street map, tom tom

Downloads

358

Readme

Build Status Coverage Status NPM version Greenkeeper badge Commitizen friendly Conventional Commits

Geocoder

Description

Geocoder is a Typescript library which helps you build geo-aware applications by providing a powerful abstraction layer for geocoding manipulations.

Installation

$ npm i @goparrot/geocoder reflect-metadata axios

⚠️️ Each reflect-metadata installation has its own metadata storage, from which it reads and writes from. So if you had a project with multiple reflect-metadata packages, it could happen that in one file you write metadata in one reflect-metadata package and in another file you’re trying to retrieve this metadata accidently from the other reflect-metadata package, which of course doesn’t exist there.

Usage

Minimal

In the code snippet below we use Google provider.

import 'reflect-metadata';
import { Distance, Location, Geocoder, GoogleMapsProvider, Suggestion } from '@goparrot/geocoder';
import axios, { AxiosInstance } from 'axios';

const axios: AxiosInstance = axios.create();

const provider: GoogleMapsProvider = new GoogleMapsProvider(axios, 'YOUR_API_KEY');

const geocoder: Geocoder = new Geocoder(provider);

(async () => {
    try {
        const locations: Location[] = await geocoder.geocode({
            address: '1158 E 89th St, Chicago, IL 60619, USA',
        });

        console.info({ locations });
    } catch (err) {
        console.error(err);
    }

    try {
        const locations: Location[] = await geocoder.reverse({
            lat: 41.7340186,
            lon: -87.5960762,
        });

        console.info({ locations });
    } catch (err) {
        console.error(err);
    }

    try {
        const suggestions: Suggestion[] = await geocoder.suggest({
            address: '1158 E 89th St',
        });

        console.info({ suggestions });
    } catch (err) {
        console.error(err);
    }

    try {
        const location: Location = await geocoder.placeDetails({
            placeId: 'SOME_GOOGLE_PLACE_ID',
        });

        console.info({ location });
    } catch (err) {
        console.error(err);
    }

    try {
        const distance: Distance = await geocoder.distance({
            from: {
                lat: 40.871994,
                lon: -74.425937,
            },
            to: {
                lat: 40.863008,
                lon: -74.385286,
            },
            mode: TravelModeEnum.DRIVING,
        });

        console.info({ distance });
    } catch (err) {
        console.error(err);
    }
})();

Advanced

In the code snippet below we use Here provider.

import 'reflect-metadata';
import { Location, Geocoder, HereProvider, LoggerInterface } from '@goparrot/geocoder';
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';

// You can use any logger that fits the LoggerInterface
const logger: LoggerInterface = console;

// Set timeout for all requests
const axios: AxiosInstance = axios.create({
    timeout: 5000,
});

// You can log all requests
axios.interceptors.request.use((request: AxiosRequestConfig) => {
    logger.debug('api request', request);

    return request;
});

// You can log all responses
axios.interceptors.response.use((response: AxiosResponse): AxiosResponse => {
    logger.debug(`api response ${response.status}`, response.data);

    return response;
});

/**
 * Caching adapter for axios. Store request results in a configurable store to prevent unneeded network requests.
 * @link {https://github.com/RasCarlito/axios-cache-adapter}
 */

const provider: HereProvider = new HereProvider(axios, 'YOUR_APP_ID', 'YOUR_APP_CODE');

const geocoder: Geocoder = new Geocoder(provider);
geocoder.setLogger(logger);

(async () => {
    try {
        const locations: Location[] = await geocoder.geocode({
            // accuracy: AccuracyEnum.HOUSE_NUMBER,
            address: '1158 E 89th St, Chicago, IL 60619, USA',
            countryCode: 'US',
            // postalCode: '60619',
            // state: 'Illinois',
            // stateCode: 'IL',
            // city: 'Chicago',
            // language: 'en', // default
            // limit: 5, // default
            // fillMissingQueryProperties: true, // default
            withRaw: true, // default false
        });

        logger.info('locations', { locations });
    } catch (err) {
        logger.error(err);
    }

    try {
        const locations: Location[] = await geocoder.reverse({
            // accuracy: AccuracyEnum.HOUSE_NUMBER,
            lat: 41.7340186,
            lon: -87.5960762,
            countryCode: 'US',
            // language: 'en', // default
            // limit: 5, // default
            // withRaw: false, // default
        });

        console.info('locations', { locations });
    } catch (err) {
        console.error(err);
    }
})();

Providers

Legend:

  • ✅ - Implemented / ready to use
  • 🚫 - Provider doesn't support it
  • ⌛ - In progress
  • 🆘 - Need help with implementation
  • 🔍️ - Need to investigate if supported by provider

Location

World

| Provider | Geocode | Reverse | Suggest | Place Details | Distance | | :---------------------------------------------------------------------------------------- | :------ | :------ | :------ | :------------ | :------- | | Algolia Places | 🆘 | 🆘️ | 🆘 | 🆘 | 🔍 | | ArcGIS Online | ✅ | ✅ | ✅️ | ✅ | 🔍 | | Bing Maps | 🆘 | 🆘️ | 🔍️ | 🆘 | 🔍 | | Geonames | 🆘 | 🆘️ | 🔍️ | 🆘 | 🔍 | | Google Maps | ✅ | ✅ | ✅ | ✅ | ✅ | | Here | ✅ | ✅ | ✅ | ✅ | 🔍 | | LocationIQ | 🆘 | 🆘️ | 🔍️ | 🔍 | 🔍 | | Mapbox | 🆘 | 🆘️ | 🔍️ | 🔍 | 🔍 | | MapQuest | ✅ | ✅ | 🚫️ | 🚫 | 🔍 | | Mapzen | 🆘 | 🆘️ | 🔍️ | 🔍 | 🔍 | | Nominatim | 🆘 | 🆘️ | 🔍️ | 🔍 | 🔍 | | OpenCage | 🆘 | 🆘️ | 🔍️ | 🔍 | 🔍 | | Photon | 🆘 | 🆘️ | 🔍️ | 🔍 | 🔍 | | PickPoint | 🆘 | 🆘️ | 🔍️ | 🔍 | 🔍 | | TomTom | 🆘 | 🆘️ | 🔍️ | 🔍 | 🔍 | | Yandex | 🆘 | 🆘️ | 🔍️ | 🔍 | 🆘️ |

Special Geocoders and Providers

The ChainProvider

The ChainProvider is a special provider that takes a list of providers and iterates over this list to get information. Note that it stops its iteration when a provider returns a result.

import 'reflect-metadata';
import axios, { AxiosInstance } from 'axios';
import { Location, ChainProvider, HereProvider, MapQuestProvider, ProviderAggregator } from '@goparrot/geocoder';

const axios: AxiosInstance = axios.create({
    timeout: 5000,
});

const chainProvider: ChainProvider = new ChainProvider([new MapQuestProvider(axios, 'YOUR_API_KEY'), new HereProvider(axios, 'YOUR_APP_ID', 'YOUR_APP_CODE')]);

const geocoder: ProviderAggregator = new ProviderAggregator([chainProvider]);

(async () => {
    try {
        const locations: Location[] = await geocoder.geocode({
            address: '1158 E 89th St, Chicago, IL 60619, USA',
        });

        console.info({ locations });
    } catch (err) {
        console.error(err);
    }
})();

The ProviderAggregator

The ProviderAggregator is used to register several providers so that you can manualy decide which provider to use later on.

import 'reflect-metadata';
import axios, { AxiosInstance } from 'axios';
import { Location, GoogleMapsProvider, HereProvider, ProviderAggregator, MapQuestProvider } from '@goparrot/geocoder';

const axios: AxiosInstance = axios.create({
    timeout: 5000,
});

const geocoder: ProviderAggregator = new ProviderAggregator([
    new MapQuestProvider(axios, 'YOUR_API_KEY'),
    new HereProvider(axios, 'YOUR_APP_ID', 'YOUR_APP_CODE'),
]);

geocoder.registerProvider(new GoogleMapsProvider(axios, 'YOUR_API_KEY'));

(async () => {
    try {
        const locations: Location[] = await geocoder.using(GoogleMapsProvider).geocode({
            address: '1158 E 89th St, Chicago, IL 60619, USA',
        });

        console.info({ locations });
    } catch (err) {
        console.error(err);
    }
})();

The ProviderAggregator's API is fluent, meaning you can write:

const locations: Location[] = geocoder.registerProvider(new MyCustomProvider(axios)).using(MyCustomProvider).geocode({
    // ...
});

The using() method allows you to choose the provider to use by its class name. When you deal with multiple providers, you may want to choose one of them. The default behavior is to use the first one, but it can be annoying.

Versioning

Geocoder follows Semantic Versioning.

Contributing

See CONTRIBUTING file.

Unit Tests

In order to run the test suite, install the development dependencies:

$ npm i

Then, run the following command:

$ npm run coverage

Background

Inspired by geocoder-php/geocoder

License

Geocoder is MIT licensed.