geocodio-library-node
Version:
geocod.io geocoding API library
711 lines (598 loc) • 19.1 kB
Markdown
# geocod.io Node library [![NPM version][npm-image]][npm-url]
> Library for performing forward and reverse address geocoding for addresses or coordinates in the US and Canada, with support for distance calculations.
<!-- toc -->
- [Installation](#installation)
- [Usage](#usage)
* [Single geocoding](#single-geocoding)
* [Batch geocoding](#batch-geocoding)
* [Field appends](#field-appends)
* [Address components](#address-components)
* [Limit results](#limit-results)
* [Distance calculation](#distance-calculation)
* [Distance matrix](#distance-matrix)
* [Async distance jobs](#async-distance-jobs)
* [Geocoding with distance](#geocoding-with-distance)
* [Lists](#lists)
* [Create A List](#create-a-list)
* [Get List Status](#get-list-status)
* [Get All Lists](#get-all-lists)
* [Download A List](#download-a-list)
* [Delete A List](#delete-a-list)
- [Testing](#testing)
- [Changelog](#changelog)
- [Security](#security)
- [License](#license)
<!-- tocstop -->
## Installation
You can install the package via npm or yarn (pick one):
```bash
$ npm install --save geocodio-library-node
$ yarn add geocodio-library-node
```
## Usage
> Don't have an API key yet? Sign up at [https://dash.geocod.io](https://dash.geocod.io) to get an API key. The first 2,500 lookups per day are free.
### Single geocoding
```javascript
const Geocodio = require('geocodio-library-node');
const geocoder = new Geocodio('YOUR_API_KEY');
// const geocoder = new Geocodio('YOUR_API_KEY', 'api.enterprise.geocod.io'); // optionally overwrite the API hostname
geocoder
.geocode('1109 N Highland St, Arlington, VA')
.then(response => {
console.log(response);
})
/*
response => {
"results": [
{
"address_components": {
"number": "1109",
"predirectional": "N",
"street": "Highland",
"suffix": "St",
"formatted_street": "N Highland St",
"city": "Arlington",
"county": "Arlington County",
"state_province": "VA",
"postal_code": "22201",
"country": "US"
},
"formatted_address": "1109 N Highland St, Arlington, VA 22201",
"location": {
"lat": 38.886672,
"lng": -77.094735
},
"accuracy": 1,
"accuracy_type": "rooftop",
"source": "Arlington"
},
{
"address_components": {
"number": "1109",
"predirectional": "N",
"street": "Highland",
"suffix": "St",
"formatted_street": "N Highland St",
"city": "Arlington",
"county": "Arlington County",
"state_province": "VA",
"postal_code": "22201",
"country": "US"
},
"formatted_address": "1109 N Highland St, Arlington, VA 22201",
"location": {
"lat": 38.886665,
"lng": -77.094733
},
"accuracy": 1,
"accuracy_type": "rooftop",
"source": "Virginia Geographic Information Network (VGIN)"
}
]
}
*/
.catch(error => {
console.error(error);
});
geocoder.reverse('38.9002898,-76.9990361')
.then(response => { ... })
.catch(err => { ... });
geocoder.reverse([38.9002898, -76.9990361])
.then(response => { ... })
.catch(err => { ... });
```
> Note: You can read more about accuracy scores, accuracy types, input formats and more at https://www.geocod.io/docs/
### Batch geocoding
To batch geocode, simply pass an array of addresses or coordinates instead of a single string
```javascript
geocoder.geocode([
'1109 N Highland St, Arlington VA',
'525 University Ave, Toronto, ON, Canada',
'4410 S Highway 17 92, Casselberry FL',
'15000 NE 24th Street, Redmond WA',
'17015 Walnut Grove Drive, Morgan Hill CA'
])
.then(response => { ... })
.catch(err => { ... });
geocoder.reverse([
'35.9746000,-77.9658000',
'32.8793700,-96.6303900',
'33.8337100,-117.8362320',
'35.4171240,-80.6784760'
])
.then(response => { ... })
.catch(err => { ... });
// Optionally supply a custom key that will be returned along with results
geocoder.geocode({
'MyId1': '1109 N Highland St, Arlington VA',
'MyId2': '525 University Ave, Toronto, ON, Canada',
'MyId3': '4410 S Highway 17 92, Casselberry FL',
'MyId4': '15000 NE 24th Street, Redmond WA',
'MyId5': '17015 Walnut Grove Drive, Morgan Hill CA'
})
.then(response => { ... })
.catch(err => { ... });
```
### Field appends
Geocodio allows you to append additional data points such as congressional districts, census codes, timezone, ACS survey results and [much much more](https://www.geocod.io/docs/#fields).
To request additional fields, simply supply them as an array as the second parameter
```javascript
geocoder.geocode(
[
'1109 N Highland St, Arlington VA',
'525 University Ave, Toronto, ON, Canada'
],
[ 'cd', 'timezone' ]
)
.then(response => { ... })
.catch(err => { ... });
geocoder.reverse('38.9002898,-76.9990361', ['census2010'])
.then(response => { ... })
.catch(err => { ... });
```
### Address components
For forward geocoding requests it is possible to supply [individual address components](https://www.geocod.io/docs/#single-address) instead of a full address string. This works for both single and batch geocoding requests.
```javascript
geocoder.geocode({
street: '1109 N Highland St',
city: 'Arlington',
state_province: 'VA',
postal_code: '22201'
})
.then(response => { ... })
.catch(err => { ... });
geocoder.geocode([
{
street: '1109 N Highland St',
city: 'Arlington',
state_province: 'VA'
},
{
street: '525 University Ave',
city: 'Toronto',
state_province: 'ON',
country: 'Canada',
},
])
.then(response => { ... })
.catch(err => { ... });
```
### Limit results
Optionally limit the number of maximum geocoding results by using the third parameter on `geocode(...)` or `reverse(...)`
```javascript
// Only get the frst result
geocoder.geocode('1109 N Highland St, Arlington, VA', [], 1)
.then(response => { ... })
.catch(err => { ... });
// Return up to 5 geocoding results
geocoder.reverse('38.9002898,-76.9990361', ['timezone'], 5)
.then(response => { ... })
.catch(err => { ... });
```
### Distance calculations
Calculate distances from a single origin to multiple destinations, or compute full distance matrices.
#### Coordinate format with custom IDs
You can add custom identifiers to coordinates using the `lat,lng,id` format. The ID will be returned in the response, making it easy to match results back to your data:
```javascript
// String format with ID
'37.7749,-122.4194,warehouse_1'
// Array format with ID
[37.7749, -122.4194, 'warehouse_1']
// Object format with ID
{ lat: 37.7749, lng: -122.4194, id: 'warehouse_1' }
// Using the Coordinate class
new Coordinate(37.7749, -122.4194, 'warehouse_1')
// The ID is returned in the response:
/*
{
"query": "37.7749,-122.4194,warehouse_1",
"location": [37.7749, -122.4194],
"id": "warehouse_1",
"distance_miles": 3.2,
"distance_km": 5.1
}
*/
```
#### Distance mode and units
The SDK provides enums for type-safe distance configuration:
```javascript
const {
Geocodio,
Coordinate,
DistanceMode,
DistanceUnits,
DistanceOrderBy,
DistanceSortOrder
} = require('geocodio-library-node');
// Available modes
DistanceMode.Straightline // Default - great-circle (as the crow flies)
DistanceMode.Driving // Road network routing with duration
DistanceMode.Haversine // Alias for Straightline
// Available units
DistanceUnits.Miles // Default
DistanceUnits.Kilometers // or DistanceUnits.Km
// Sorting options
DistanceOrderBy.Distance // Default
DistanceOrderBy.Duration
DistanceSortOrder.Asc // Default
DistanceSortOrder.Desc
```
> **Note:** The default mode is `straightline` (great-circle distance). Use `DistanceMode.Driving` if you need road network routing with duration estimates.
#### Add distance to geocoding requests
You can add distance calculations to existing geocode or reverse geocode requests. Each geocoded result will include a `destinations` array with distances to each destination.
```javascript
const geocoder = new Geocodio('YOUR_API_KEY');
// Geocode an address and calculate distances to store locations
geocoder.geocode(
'1600 Pennsylvania Ave NW, Washington DC',
[], // fields
null, // limit
{ // distance options
destinations: [
'38.9072,-77.0369,store_dc',
'39.2904,-76.6122,store_baltimore',
'39.9526,-75.1652,store_philly'
],
distanceMode: DistanceMode.Driving,
distanceUnits: DistanceUnits.Miles
}
)
.then(response => {
console.log(response.results[0].destinations);
/*
[
{
"query": "38.9072,-77.0369,store_dc",
"location": [38.9072, -77.0369],
"id": "store_dc",
"distance_miles": 0.8,
"distance_km": 1.3,
"duration_seconds": 180
},
...
]
*/
});
// Reverse geocode with distances
geocoder.reverse(
'38.8977,-77.0365',
[],
null,
{
destinations: ['38.9072,-77.0369,capitol', '38.8895,-77.0353,monument'],
distanceMode: DistanceMode.Straightline
}
)
.then(response => { ... });
// With filtering - find nearest 3 stores within 50 miles
geocoder.geocode(
'1600 Pennsylvania Ave NW, Washington DC',
[],
null,
{
destinations: [
'38.9072,-77.0369,store_1',
'39.2904,-76.6122,store_2',
'39.9526,-75.1652,store_3',
'40.7128,-74.0060,store_4'
],
distanceMode: DistanceMode.Driving,
distanceMaxResults: 3,
distanceMaxDistance: 50.0,
distanceOrderBy: DistanceOrderBy.Distance,
distanceSortOrder: DistanceSortOrder.Asc
}
)
.then(response => { ... });
```
#### Single origin to multiple destinations
```javascript
const geocoder = new Geocodio('YOUR_API_KEY');
// Calculate distances from one origin to multiple destinations
geocoder.distance(
'37.7749,-122.4194,headquarters', // Origin with ID
[
'37.7849,-122.4094,customer_a',
'37.7949,-122.3994,customer_b',
'37.8049,-122.4294,customer_c'
]
)
.then(response => {
console.log(response);
/*
{
"origin": {
"query": "37.7749,-122.4194,headquarters",
"location": [37.7749, -122.4194],
"id": "headquarters"
},
"destinations": [
{
"query": "37.7849,-122.4094,customer_a",
"location": [37.7849, -122.4094],
"id": "customer_a",
"distance_miles": 0.9,
"distance_km": 1.4
},
...
]
}
*/
});
// Use driving mode for road network routing (includes duration)
geocoder.distance(
'37.7749,-122.4194',
['37.7849,-122.4094'],
{ mode: DistanceMode.Driving }
)
.then(response => {
console.log(response.destinations[0].duration_seconds); // e.g., 180
});
// With all filtering and sorting options
geocoder.distance(
'37.7749,-122.4194,warehouse',
[
'37.7849,-122.4094,store_1',
'37.7949,-122.3994,store_2',
'37.8049,-122.4294,store_3'
],
{
mode: DistanceMode.Driving,
units: DistanceUnits.Kilometers,
maxResults: 2,
maxDistance: 10.0,
orderBy: DistanceOrderBy.Distance,
sortOrder: DistanceSortOrder.Asc
}
)
.then(response => { ... });
// Using Coordinate class
const origin = new Coordinate(37.7749, -122.4194, 'warehouse');
const destinations = [
new Coordinate(37.7849, -122.4094, 'store_1'),
new Coordinate(37.7949, -122.3994, 'store_2')
];
geocoder.distance(origin, destinations)
.then(response => { ... });
// Array format for coordinates (with or without ID)
geocoder.distance(
[37.7749, -122.4194], // Without ID
[[37.7849, -122.4094, 'dest_1']] // With ID as third element
)
.then(response => { ... });
```
#### Distance matrix (multiple origins × destinations)
```javascript
// Calculate full distance matrix with custom IDs
geocoder.distanceMatrix(
[
'37.7749,-122.4194,warehouse_sf',
'37.8049,-122.4294,warehouse_oak'
],
[
'37.7849,-122.4094,customer_1',
'37.7949,-122.3994,customer_2'
]
)
.then(response => {
console.log(response);
/*
{
"mode": "driving",
"results": [
{
"origin": {
"query": "37.7749,-122.4194,warehouse_sf",
"location": [37.7749, -122.4194],
"id": "warehouse_sf"
},
"destinations": [
{
"query": "37.7849,-122.4094,customer_1",
"location": [37.7849, -122.4094],
"id": "customer_1",
"distance_miles": 0.9,
"distance_km": 1.4
},
...
]
},
{
"origin": { ..., "id": "warehouse_oak" },
"destinations": [...]
}
]
}
*/
});
// With driving mode and kilometers
geocoder.distanceMatrix(
['37.7749,-122.4194'],
['37.7849,-122.4094'],
{ mode: DistanceMode.Driving, units: DistanceUnits.Kilometers }
)
.then(response => { ... });
// Using object format
const origins = [
{ lat: 37.7749, lng: -122.4194, id: 'warehouse_sf' },
{ lat: 37.8049, lng: -122.4294, id: 'warehouse_oak' }
];
const destinations = [
{ lat: 37.7849, lng: -122.4094, id: 'customer_1' },
{ lat: 37.7949, lng: -122.3994, id: 'customer_2' }
];
geocoder.distanceMatrix(origins, destinations)
.then(response => { ... });
```
#### Nearest mode (find closest destinations)
```javascript
// Find up to 2 nearest destinations from each origin
geocoder.distanceMatrix(
['37.7749,-122.4194'],
['37.7849,-122.4094', '37.7949,-122.3994', '37.8049,-122.4294'],
{ maxResults: 2 }
)
.then(response => { ... });
// Filter by maximum distance (in miles or km depending on units)
geocoder.distanceMatrix(
['37.7749,-122.4194'],
[...destinations],
{ maxDistance: 2.0 }
)
.then(response => { ... });
// Filter by minimum and maximum distance
geocoder.distanceMatrix(
['37.7749,-122.4194'],
[...destinations],
{ minDistance: 1.0, maxDistance: 10.0 }
)
.then(response => { ... });
// Filter by duration (seconds, driving mode only)
geocoder.distanceMatrix(
['37.7749,-122.4194'],
[...destinations],
{
mode: DistanceMode.Driving,
maxDuration: 300, // 5 minutes
minDuration: 60 // 1 minute minimum
}
)
.then(response => { ... });
// Sort by duration descending
geocoder.distanceMatrix(
['37.7749,-122.4194'],
[...destinations],
{
mode: DistanceMode.Driving,
maxResults: 5,
orderBy: DistanceOrderBy.Duration,
sortOrder: DistanceSortOrder.Desc
}
)
.then(response => { ... });
```
#### Async distance matrix jobs
For large distance matrix calculations, use async jobs that process in the background.
```javascript
// Create a new distance matrix job
geocoder.createDistanceMatrixJob(
'My Distance Calculation',
['37.7749,-122.4194', '37.8049,-122.4294'],
['37.7849,-122.4094', '37.7949,-122.3994'],
{
mode: DistanceMode.Driving,
units: DistanceUnits.Miles,
callbackUrl: 'https://example.com/webhook' // Optional
}
)
.then(response => {
console.log(response);
// { id: 123, status: 'ENQUEUED', total_calculations: 4 }
});
// Or use list IDs from previously uploaded lists
geocoder.createDistanceMatrixJob(
'Distance from List',
12345, // Origins list ID
67890, // Destinations list ID
{ mode: DistanceMode.Straightline }
)
.then(response => { ... });
// Check job status
geocoder.distanceMatrixJobStatus(123)
.then(response => {
console.log(response.data.status); // 'ENQUEUED', 'PROCESSING', 'COMPLETED', or 'FAILED'
console.log(response.data.progress); // 0-100
});
// List all jobs (paginated)
geocoder.distanceMatrixJobs()
.then(response => { ... });
geocoder.distanceMatrixJobs(2) // Page 2
.then(response => { ... });
// Get results when complete (same format as distanceMatrix response)
geocoder.getDistanceMatrixJobResults(123)
.then(response => {
console.log(response.results);
});
// Or download to a file for very large results
geocoder.downloadDistanceMatrixJob(123, 'results.json')
.then(() => console.log('Downloaded!'));
// Delete a job
geocoder.deleteDistanceMatrixJob(123)
.then(() => console.log('Deleted!'));
```
### Lists
List methods are nested within `.list`. To access list methods, be sure to to run `geocoder.list` and then include the task method you would like to utilize.
#### Create A List
To create and upload a new list using an existing .CSV file, run `geocoder.list.create(...)` and pass in your filename/file path.
You may also need to pass in some additional parameters:
* Direction: Use the default string `"forward"`.
* Format: Use the default string `"{{A}} {{B}} {{C}} {{D}}"`
* Callback: A callback URL.
```javascript
geocoder.list.create(
`${__dirname}/stubs/sample_list.csv`,
"forward",
"{{A}} {{B}} {{C}} {{D}}",
"https://example.com/my-callback"
)
```
#### Get List Status
To retrieve the current status of your list, pass your list's ID into `geocoder.list.status(...)`.
```javascript
geocoder.list.status(1234567)
.then(response => { ... })
.catch(err => { ... });
```
#### Get All Lists
To retrieve all available lists, run `geocoder.list.all()`. You do not need to pass anything into this function.
```javascript
geocoder.list.all()
.then(response => { ... })
.catch(err => { ... });
```
#### Download A List
To download a list, run `geocoder.list.download(...)` and pass in the ID of the list you'd like to download, as well as a string that includes a filename. Be sure to include a `.csv` file extension.
```javascript
geocoder.list.download(1234567, "geocoded_file.csv")
.then(response => { ...})
.catch(err => { ... });
```
#### Delete A List
To delete a list, run `geocoder.list.deleteList(...)` and pass in the ID of the list you'd like to delete.
```javascript
geocoder.list.delete(1234567)
.then(response => { ... })
.catch(err => { ... });
```
## Testing
```bash
$ npm test
```
## Changelog
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
## Security
If you discover any security related issues, please email security@geocod.io instead of using the issue tracker.
## License
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
[npm-image]: https://img.shields.io/npm/v/geocodio-library-node
[npm-url]: https://npmjs.org/package/geocodio-library-node