Geocoder
Geocoder is a Typescript library which helps you build geo-aware applications by providing a powerful abstraction layer for geocoding manipulations
Install / Use
/learn @goparrot/GeocoderREADME
Geocoder
<p align="center"> <a href="https://github.com/goparrot/geocoder" target="blank"><img src="https://upload.wikimedia.org/wikipedia/commons/7/72/OpenStreetMap-Logo-2006.svg" width="354" alt="Geocoder Logo" /></a> </p>Description
Geocoder is a Typescript library which helps you build geo-aware applications by providing a powerful abstraction layer for geocoding manipulations.
- Installation
- Usage
- Providers
- Special Geocoders and Providers
- Versioning
- Contributing
- Unit Tests
- Background
- License
Installation
$ npm i @goparrot/geocoder reflect-metadata axios
<sub>⚠️️ 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.</sub>
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',
Related Skills
node-connect
342.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
85.3kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
Writing Hookify Rules
85.3kThis skill should be used when the user asks to "create a hookify rule", "write a hook rule", "configure hookify", "add a hookify rule", or needs guidance on hookify rule syntax and patterns.
review-duplication
99.6kUse this skill during code reviews to proactively investigate the codebase for duplicated functionality, reinvented wheels, or failure to reuse existing project best practices and shared utilities.
