geocodio-library-node 1.11.0 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # geocod.io Node library [![NPM version][npm-image]][npm-url]
2
- > Library for performing forward and reverse address geocoding for addresses or coordinates in the US and Canada.
2
+ > Library for performing forward and reverse address geocoding for addresses or coordinates in the US and Canada, with support for distance calculations.
3
3
 
4
4
  <!-- toc -->
5
5
 
@@ -10,6 +10,10 @@
10
10
  * [Field appends](#field-appends)
11
11
  * [Address components](#address-components)
12
12
  * [Limit results](#limit-results)
13
+ * [Distance calculation](#distance-calculation)
14
+ * [Distance matrix](#distance-matrix)
15
+ * [Async distance jobs](#async-distance-jobs)
16
+ * [Geocoding with distance](#geocoding-with-distance)
13
17
  * [Lists](#lists)
14
18
  * [Create A List](#create-a-list)
15
19
  * [Get List Status](#get-list-status)
@@ -231,6 +235,410 @@ geocoder.reverse('38.9002898,-76.9990361', ['timezone'], 5)
231
235
  .catch(err => { ... });
232
236
  ```
233
237
 
238
+ ### Distance calculations
239
+
240
+ Calculate distances from a single origin to multiple destinations, or compute full distance matrices.
241
+
242
+ #### Coordinate format with custom IDs
243
+
244
+ 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:
245
+
246
+ ```javascript
247
+ // String format with ID
248
+ '37.7749,-122.4194,warehouse_1'
249
+
250
+ // Array format with ID
251
+ [37.7749, -122.4194, 'warehouse_1']
252
+
253
+ // Object format with ID
254
+ { lat: 37.7749, lng: -122.4194, id: 'warehouse_1' }
255
+
256
+ // Using the Coordinate class
257
+ new Coordinate(37.7749, -122.4194, 'warehouse_1')
258
+
259
+ // The ID is returned in the response:
260
+ /*
261
+ {
262
+ "query": "37.7749,-122.4194,warehouse_1",
263
+ "location": [37.7749, -122.4194],
264
+ "id": "warehouse_1",
265
+ "distance_miles": 3.2,
266
+ "distance_km": 5.1
267
+ }
268
+ */
269
+ ```
270
+
271
+ #### Distance mode and units
272
+
273
+ The SDK provides enums for type-safe distance configuration:
274
+
275
+ ```javascript
276
+ const {
277
+ Geocodio,
278
+ Coordinate,
279
+ DistanceMode,
280
+ DistanceUnits,
281
+ DistanceOrderBy,
282
+ DistanceSortOrder
283
+ } = require('geocodio-library-node');
284
+
285
+ // Available modes
286
+ DistanceMode.Straightline // Default - great-circle (as the crow flies)
287
+ DistanceMode.Driving // Road network routing with duration
288
+ DistanceMode.Haversine // Alias for Straightline
289
+
290
+ // Available units
291
+ DistanceUnits.Miles // Default
292
+ DistanceUnits.Kilometers // or DistanceUnits.Km
293
+
294
+ // Sorting options
295
+ DistanceOrderBy.Distance // Default
296
+ DistanceOrderBy.Duration
297
+
298
+ DistanceSortOrder.Asc // Default
299
+ DistanceSortOrder.Desc
300
+ ```
301
+
302
+ > **Note:** The default mode is `straightline` (great-circle distance). Use `DistanceMode.Driving` if you need road network routing with duration estimates.
303
+
304
+ #### Add distance to geocoding requests
305
+
306
+ 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.
307
+
308
+ ```javascript
309
+ const geocoder = new Geocodio('YOUR_API_KEY');
310
+
311
+ // Geocode an address and calculate distances to store locations
312
+ geocoder.geocode(
313
+ '1600 Pennsylvania Ave NW, Washington DC',
314
+ [], // fields
315
+ null, // limit
316
+ { // distance options
317
+ destinations: [
318
+ '38.9072,-77.0369,store_dc',
319
+ '39.2904,-76.6122,store_baltimore',
320
+ '39.9526,-75.1652,store_philly'
321
+ ],
322
+ distanceMode: DistanceMode.Driving,
323
+ distanceUnits: DistanceUnits.Miles
324
+ }
325
+ )
326
+ .then(response => {
327
+ console.log(response.results[0].destinations);
328
+ /*
329
+ [
330
+ {
331
+ "query": "38.9072,-77.0369,store_dc",
332
+ "location": [38.9072, -77.0369],
333
+ "id": "store_dc",
334
+ "distance_miles": 0.8,
335
+ "distance_km": 1.3,
336
+ "duration_seconds": 180
337
+ },
338
+ ...
339
+ ]
340
+ */
341
+ });
342
+
343
+ // Reverse geocode with distances
344
+ geocoder.reverse(
345
+ '38.8977,-77.0365',
346
+ [],
347
+ null,
348
+ {
349
+ destinations: ['38.9072,-77.0369,capitol', '38.8895,-77.0353,monument'],
350
+ distanceMode: DistanceMode.Straightline
351
+ }
352
+ )
353
+ .then(response => { ... });
354
+
355
+ // With filtering - find nearest 3 stores within 50 miles
356
+ geocoder.geocode(
357
+ '1600 Pennsylvania Ave NW, Washington DC',
358
+ [],
359
+ null,
360
+ {
361
+ destinations: [
362
+ '38.9072,-77.0369,store_1',
363
+ '39.2904,-76.6122,store_2',
364
+ '39.9526,-75.1652,store_3',
365
+ '40.7128,-74.0060,store_4'
366
+ ],
367
+ distanceMode: DistanceMode.Driving,
368
+ distanceMaxResults: 3,
369
+ distanceMaxDistance: 50.0,
370
+ distanceOrderBy: DistanceOrderBy.Distance,
371
+ distanceSortOrder: DistanceSortOrder.Asc
372
+ }
373
+ )
374
+ .then(response => { ... });
375
+ ```
376
+
377
+ #### Single origin to multiple destinations
378
+
379
+ ```javascript
380
+ const geocoder = new Geocodio('YOUR_API_KEY');
381
+
382
+ // Calculate distances from one origin to multiple destinations
383
+ geocoder.distance(
384
+ '37.7749,-122.4194,headquarters', // Origin with ID
385
+ [
386
+ '37.7849,-122.4094,customer_a',
387
+ '37.7949,-122.3994,customer_b',
388
+ '37.8049,-122.4294,customer_c'
389
+ ]
390
+ )
391
+ .then(response => {
392
+ console.log(response);
393
+ /*
394
+ {
395
+ "origin": {
396
+ "query": "37.7749,-122.4194,headquarters",
397
+ "location": [37.7749, -122.4194],
398
+ "id": "headquarters"
399
+ },
400
+ "destinations": [
401
+ {
402
+ "query": "37.7849,-122.4094,customer_a",
403
+ "location": [37.7849, -122.4094],
404
+ "id": "customer_a",
405
+ "distance_miles": 0.9,
406
+ "distance_km": 1.4
407
+ },
408
+ ...
409
+ ]
410
+ }
411
+ */
412
+ });
413
+
414
+ // Use driving mode for road network routing (includes duration)
415
+ geocoder.distance(
416
+ '37.7749,-122.4194',
417
+ ['37.7849,-122.4094'],
418
+ { mode: DistanceMode.Driving }
419
+ )
420
+ .then(response => {
421
+ console.log(response.destinations[0].duration_seconds); // e.g., 180
422
+ });
423
+
424
+ // With all filtering and sorting options
425
+ geocoder.distance(
426
+ '37.7749,-122.4194,warehouse',
427
+ [
428
+ '37.7849,-122.4094,store_1',
429
+ '37.7949,-122.3994,store_2',
430
+ '37.8049,-122.4294,store_3'
431
+ ],
432
+ {
433
+ mode: DistanceMode.Driving,
434
+ units: DistanceUnits.Kilometers,
435
+ maxResults: 2,
436
+ maxDistance: 10.0,
437
+ orderBy: DistanceOrderBy.Distance,
438
+ sortOrder: DistanceSortOrder.Asc
439
+ }
440
+ )
441
+ .then(response => { ... });
442
+
443
+ // Using Coordinate class
444
+ const origin = new Coordinate(37.7749, -122.4194, 'warehouse');
445
+ const destinations = [
446
+ new Coordinate(37.7849, -122.4094, 'store_1'),
447
+ new Coordinate(37.7949, -122.3994, 'store_2')
448
+ ];
449
+
450
+ geocoder.distance(origin, destinations)
451
+ .then(response => { ... });
452
+
453
+ // Array format for coordinates (with or without ID)
454
+ geocoder.distance(
455
+ [37.7749, -122.4194], // Without ID
456
+ [[37.7849, -122.4094, 'dest_1']] // With ID as third element
457
+ )
458
+ .then(response => { ... });
459
+ ```
460
+
461
+ #### Distance matrix (multiple origins × destinations)
462
+
463
+ ```javascript
464
+ // Calculate full distance matrix with custom IDs
465
+ geocoder.distanceMatrix(
466
+ [
467
+ '37.7749,-122.4194,warehouse_sf',
468
+ '37.8049,-122.4294,warehouse_oak'
469
+ ],
470
+ [
471
+ '37.7849,-122.4094,customer_1',
472
+ '37.7949,-122.3994,customer_2'
473
+ ]
474
+ )
475
+ .then(response => {
476
+ console.log(response);
477
+ /*
478
+ {
479
+ "mode": "driving",
480
+ "results": [
481
+ {
482
+ "origin": {
483
+ "query": "37.7749,-122.4194,warehouse_sf",
484
+ "location": [37.7749, -122.4194],
485
+ "id": "warehouse_sf"
486
+ },
487
+ "destinations": [
488
+ {
489
+ "query": "37.7849,-122.4094,customer_1",
490
+ "location": [37.7849, -122.4094],
491
+ "id": "customer_1",
492
+ "distance_miles": 0.9,
493
+ "distance_km": 1.4
494
+ },
495
+ ...
496
+ ]
497
+ },
498
+ {
499
+ "origin": { ..., "id": "warehouse_oak" },
500
+ "destinations": [...]
501
+ }
502
+ ]
503
+ }
504
+ */
505
+ });
506
+
507
+ // With driving mode and kilometers
508
+ geocoder.distanceMatrix(
509
+ ['37.7749,-122.4194'],
510
+ ['37.7849,-122.4094'],
511
+ { mode: DistanceMode.Driving, units: DistanceUnits.Kilometers }
512
+ )
513
+ .then(response => { ... });
514
+
515
+ // Using object format
516
+ const origins = [
517
+ { lat: 37.7749, lng: -122.4194, id: 'warehouse_sf' },
518
+ { lat: 37.8049, lng: -122.4294, id: 'warehouse_oak' }
519
+ ];
520
+
521
+ const destinations = [
522
+ { lat: 37.7849, lng: -122.4094, id: 'customer_1' },
523
+ { lat: 37.7949, lng: -122.3994, id: 'customer_2' }
524
+ ];
525
+
526
+ geocoder.distanceMatrix(origins, destinations)
527
+ .then(response => { ... });
528
+ ```
529
+
530
+ #### Nearest mode (find closest destinations)
531
+
532
+ ```javascript
533
+ // Find up to 2 nearest destinations from each origin
534
+ geocoder.distanceMatrix(
535
+ ['37.7749,-122.4194'],
536
+ ['37.7849,-122.4094', '37.7949,-122.3994', '37.8049,-122.4294'],
537
+ { maxResults: 2 }
538
+ )
539
+ .then(response => { ... });
540
+
541
+ // Filter by maximum distance (in miles or km depending on units)
542
+ geocoder.distanceMatrix(
543
+ ['37.7749,-122.4194'],
544
+ [...destinations],
545
+ { maxDistance: 2.0 }
546
+ )
547
+ .then(response => { ... });
548
+
549
+ // Filter by minimum and maximum distance
550
+ geocoder.distanceMatrix(
551
+ ['37.7749,-122.4194'],
552
+ [...destinations],
553
+ { minDistance: 1.0, maxDistance: 10.0 }
554
+ )
555
+ .then(response => { ... });
556
+
557
+ // Filter by duration (seconds, driving mode only)
558
+ geocoder.distanceMatrix(
559
+ ['37.7749,-122.4194'],
560
+ [...destinations],
561
+ {
562
+ mode: DistanceMode.Driving,
563
+ maxDuration: 300, // 5 minutes
564
+ minDuration: 60 // 1 minute minimum
565
+ }
566
+ )
567
+ .then(response => { ... });
568
+
569
+ // Sort by duration descending
570
+ geocoder.distanceMatrix(
571
+ ['37.7749,-122.4194'],
572
+ [...destinations],
573
+ {
574
+ mode: DistanceMode.Driving,
575
+ maxResults: 5,
576
+ orderBy: DistanceOrderBy.Duration,
577
+ sortOrder: DistanceSortOrder.Desc
578
+ }
579
+ )
580
+ .then(response => { ... });
581
+ ```
582
+
583
+ #### Async distance matrix jobs
584
+
585
+ For large distance matrix calculations, use async jobs that process in the background.
586
+
587
+ ```javascript
588
+ // Create a new distance matrix job
589
+ geocoder.createDistanceMatrixJob(
590
+ 'My Distance Calculation',
591
+ ['37.7749,-122.4194', '37.8049,-122.4294'],
592
+ ['37.7849,-122.4094', '37.7949,-122.3994'],
593
+ {
594
+ mode: DistanceMode.Driving,
595
+ units: DistanceUnits.Miles,
596
+ callbackUrl: 'https://example.com/webhook' // Optional
597
+ }
598
+ )
599
+ .then(response => {
600
+ console.log(response);
601
+ // { id: 123, status: 'ENQUEUED', total_calculations: 4 }
602
+ });
603
+
604
+ // Or use list IDs from previously uploaded lists
605
+ geocoder.createDistanceMatrixJob(
606
+ 'Distance from List',
607
+ 12345, // Origins list ID
608
+ 67890, // Destinations list ID
609
+ { mode: DistanceMode.Straightline }
610
+ )
611
+ .then(response => { ... });
612
+
613
+ // Check job status
614
+ geocoder.distanceMatrixJobStatus(123)
615
+ .then(response => {
616
+ console.log(response.data.status); // 'ENQUEUED', 'PROCESSING', 'COMPLETED', or 'FAILED'
617
+ console.log(response.data.progress); // 0-100
618
+ });
619
+
620
+ // List all jobs (paginated)
621
+ geocoder.distanceMatrixJobs()
622
+ .then(response => { ... });
623
+
624
+ geocoder.distanceMatrixJobs(2) // Page 2
625
+ .then(response => { ... });
626
+
627
+ // Get results when complete (same format as distanceMatrix response)
628
+ geocoder.getDistanceMatrixJobResults(123)
629
+ .then(response => {
630
+ console.log(response.results);
631
+ });
632
+
633
+ // Or download to a file for very large results
634
+ geocoder.downloadDistanceMatrixJob(123, 'results.json')
635
+ .then(() => console.log('Downloaded!'));
636
+
637
+ // Delete a job
638
+ geocoder.deleteDistanceMatrixJob(123)
639
+ .then(() => console.log('Deleted!'));
640
+ ```
641
+
234
642
  ### Lists
235
643
 
236
644
  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.