Node.js geocoding library supporting multiple providers for converting addresses to coordinates and vice versa
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Transform geocoding results into different output formats including GPX XML and custom string templates.
Converts geocoding results into GPX (GPS Exchange Format) XML for use with GPS devices and mapping applications.
/**
* GPX formatter configuration
*/
interface GpxFormatterConfig {
/** Formatter type */
formatter: 'gpx';
}
/**
* GPX formatter class
*/
class GpxFormatter {
constructor();
/**
* Format geocoding results as GPX XML
* @param {GeocodeResult[]} data - Array of geocoding results
* @returns {string} GPX XML string
*/
format(data: GeocodeResult[]): string;
}Usage Examples:
const NodeGeocoder = require('node-geocoder');
// Create geocoder with GPX formatter
const geocoder = NodeGeocoder('google', {
apiKey: 'YOUR_API_KEY',
formatter: 'gpx'
});
// Geocode and get GPX output
const gpxResult = await geocoder.geocode([
'Eiffel Tower, Paris',
'Big Ben, London',
'Colosseum, Rome'
]);
console.log(gpxResult);
// Output: GPX XML string with waypoints
// Save to file
const fs = require('fs');
fs.writeFileSync('locations.gpx', gpxResult);GPX Output Format:
<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" xmlns="http://www.topografix.com/GPX/1/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" creator="geocoder.js">
<wpt lat="48.8583701" lon="2.2944813">
<name></name>
</wpt>
<wpt lat="51.5007292" lon="-0.1246254">
<name></name>
</wpt>
</gpx>Formats geocoding results using customizable string patterns with placeholder substitution.
/**
* String formatter configuration
*/
interface StringFormatterConfig {
/** Formatter type */
formatter: 'string';
/** Template pattern with placeholders */
formatterPattern: string;
}
/**
* String formatter class
*/
class StringFormatter {
/**
* Create string formatter with pattern
* @param {string} pattern - Template pattern with placeholders
*/
constructor(pattern: string);
/**
* Format geocoding results using the pattern
* @param {GeocodeResult[]} data - Array of geocoding results
* @returns {string[]} Array of formatted strings
*/
format(data: GeocodeResult[]): string[];
}Pattern Placeholders:
/**
* Available placeholders for string formatter patterns
*/
interface StringPlaceholders {
'%n': 'streetNumber'; // Street number
'%S': 'streetName'; // Street name
'%z': 'zipcode'; // ZIP/postal code
'%P': 'country'; // Country name
'%p': 'countryCode'; // Country code
'%c': 'city'; // City name
'%T': 'state'; // State/province name
'%t': 'stateCode'; // State/province code
}Usage Examples:
// Create geocoder with string formatter
const geocoder = NodeGeocoder('google', {
apiKey: 'YOUR_API_KEY',
formatter: 'string',
formatterPattern: '%n %S, %c, %P %z' // "123 Main St, New York, United States 10001"
});
// Geocode and get formatted strings
const addresses = await geocoder.geocode([
'1600 Amphitheatre Parkway, Mountain View, CA',
'Times Square, New York, NY'
]);
console.log(addresses);
// Output: [
// "1600 Amphitheatre Parkway, Mountain View, United States 94043",
// " Times Square, New York, United States "
// ]
// Custom patterns for different use cases
const patterns = {
simple: '%c, %P', // "Paris, France"
detailed: '%n %S, %c %z, %P', // "123 Main St, Paris 75001, France"
coordinates: '%c (%lat, %lon)', // Not directly supported - use custom logic
postal: '%c %z' // "Paris 75001"
};
// Multiple formatters for different outputs
const cityFormatter = NodeGeocoder('google', {
apiKey: 'YOUR_API_KEY',
formatter: 'string',
formatterPattern: '%c, %P'
});
const fullFormatter = NodeGeocoder('google', {
apiKey: 'YOUR_API_KEY',
formatter: 'string',
formatterPattern: '%n %S, %c, %T %z, %P'
});Create custom formatters by processing the standard GeocodeResult objects.
/**
* Standard geocode result structure for custom formatting
*/
interface GeocodeResult {
formattedAddress: string;
latitude: number;
longitude: number;
country?: string;
countryCode?: string;
city?: string;
zipcode?: string;
streetName?: string;
streetNumber?: string;
administrativeLevels?: {
level1long?: string;
level1short?: string;
level2long?: string;
level2short?: string;
level3long?: string;
level3short?: string;
level4long?: string;
level4short?: string;
level5long?: string;
level5short?: string;
};
extra?: {
confidence?: number;
[key: string]: any;
};
provider: string;
}Custom Formatting Examples:
const NodeGeocoder = require('node-geocoder');
// Standard geocoder without formatter
const geocoder = NodeGeocoder('google', {
apiKey: 'YOUR_API_KEY'
});
// Custom JSON formatter
function formatAsJson(results) {
return results.map(result => ({
address: result.formattedAddress,
coordinates: [result.longitude, result.latitude],
components: {
street: `${result.streetNumber || ''} ${result.streetName || ''}`.trim(),
city: result.city,
country: result.country,
postal: result.zipcode
},
confidence: result.extra?.confidence,
provider: result.provider
}));
}
// Custom CSV formatter
function formatAsCsv(results) {
const header = 'address,latitude,longitude,city,country,zipcode';
const rows = results.map(r =>
`"${r.formattedAddress}",${r.latitude},${r.longitude},"${r.city || ''}","${r.country || ''}","${r.zipcode || ''}"`
);
return [header, ...rows].join('\n');
}
// Custom coordinates formatter
function formatAsCoordinates(results) {
return results.map(result =>
`${result.latitude},${result.longitude}`
);
}
// Usage
const results = await geocoder.geocode(['Paris, France', 'London, UK']);
const jsonFormat = formatAsJson(results);
const csvFormat = formatAsCsv(results);
const coordinates = formatAsCoordinates(results);
console.log('JSON:', jsonFormat);
console.log('CSV:', csvFormat);
console.log('Coordinates:', coordinates);Handle formatting errors and edge cases in result data.
/**
* Formatter error handling
*/
interface FormatterError extends Error {
message: string;
name: 'FormatterError';
}Error Handling Examples:
// String formatter requires pattern
try {
const geocoder = NodeGeocoder('google', {
apiKey: 'YOUR_API_KEY',
formatter: 'string'
// Missing formatterPattern
});
} catch (error) {
console.error(error.message); // "StringFormatter need a pattern"
}
// Handle missing data in custom formatters
function safeStringFormat(pattern, result) {
return pattern
.replace(/%n/g, result.streetNumber || '')
.replace(/%S/g, result.streetName || '')
.replace(/%z/g, result.zipcode || '')
.replace(/%P/g, result.country || '')
.replace(/%p/g, result.countryCode || '')
.replace(/%c/g, result.city || '')
.replace(/%T/g, result.administrativeLevels?.level1long || '')
.replace(/%t/g, result.administrativeLevels?.level1short || '');
}
// Robust custom formatter with error handling
function robustFormatter(results, format) {
try {
return results.map(result => {
if (!result || typeof result !== 'object') {
return 'Invalid result';
}
switch (format) {
case 'coordinates':
return `${result.latitude || 0},${result.longitude || 0}`;
case 'address':
return result.formattedAddress || 'Unknown address';
default:
return JSON.stringify(result);
}
});
} catch (error) {
console.error('Formatting error:', error);
return ['Formatting failed'];
}
}